Search in sources :

Example 1 with FloatList

use of com.mta.tehreer.collections.FloatList in project Tehreer-Android by mta452.

the class TextRun method computeTypographicExtent.

public float computeTypographicExtent(int glyphStart, int glyphEnd) {
    FloatList glyphAdvances = getGlyphAdvances();
    float extent = 0.0f;
    for (int i = glyphStart; i < glyphEnd; i++) {
        extent += glyphAdvances.get(i);
    }
    return extent;
}
Also used : FloatList(com.mta.tehreer.collections.FloatList)

Example 2 with FloatList

use of com.mta.tehreer.collections.FloatList in project Tehreer-Android by mta452.

the class ShapingResult method getCaretAdvances.

@NonNull
private float[] getCaretAdvances(@Nullable boolean[] caretStops) {
    int codeUnitCount = getCharCount();
    float[] caretAdvances = new float[codeUnitCount + 1];
    boolean isBackward = isBackward();
    FloatList glyphAdvances = getGlyphAdvances();
    IntList clusterMap = getClusterMap();
    int glyphIndex = clusterMap.get(0) + 1;
    int refIndex = glyphIndex;
    int totalStops = 0;
    int clusterStart = 0;
    for (int codeUnitIndex = 1; codeUnitIndex <= codeUnitCount; codeUnitIndex++) {
        int oldIndex = glyphIndex;
        if (codeUnitIndex != codeUnitCount) {
            glyphIndex = clusterMap.get(codeUnitIndex) + 1;
            if (caretStops != null && !caretStops[codeUnitIndex - 1]) {
                continue;
            }
            totalStops += 1;
        } else {
            totalStops += 1;
            glyphIndex = (isBackward ? 0 : getGlyphCount() + 1);
        }
        if (glyphIndex != oldIndex) {
            float clusterAdvance = 0;
            float distance = 0;
            int counter = 1;
            /* Find the advance of current cluster. */
            if (isBackward) {
                while (refIndex > glyphIndex) {
                    clusterAdvance += glyphAdvances.get(refIndex - 1);
                    refIndex -= 1;
                }
            } else {
                while (refIndex < glyphIndex) {
                    clusterAdvance += glyphAdvances.get(refIndex - 1);
                    refIndex += 1;
                }
            }
            /* Divide the advance evenly between cluster length. */
            while (clusterStart < codeUnitIndex) {
                float advance = 0;
                if (caretStops == null || caretStops[clusterStart] || clusterStart == codeUnitCount - 1) {
                    float previous = distance;
                    distance = (clusterAdvance * counter) / totalStops;
                    advance = distance - previous;
                    counter += 1;
                }
                caretAdvances[clusterStart] = advance;
                clusterStart += 1;
            }
            totalStops = 0;
        }
    }
    return caretAdvances;
}
Also used : FloatList(com.mta.tehreer.collections.FloatList) IntList(com.mta.tehreer.collections.IntList) NonNull(androidx.annotation.NonNull)

Example 3 with FloatList

use of com.mta.tehreer.collections.FloatList in project Tehreer-Android by mta452.

the class ShapeResolver method resolveTypefaces.

private static void resolveTypefaces(@NonNull String text, @NonNull Spanned spanned, @NonNull List<TextRun> runs, @NonNull ShapingRunLocator locator, @NonNull ShapingEngine engine, byte bidiLevel) {
    Paint paint = null;
    Paint.FontMetricsInt metrics = null;
    while (locator.moveNext()) {
        int runStart = locator.getRunStart();
        int runEnd = locator.getRunEnd();
        Typeface typeface = locator.getTypeface();
        checkArgument(typeface != null, "No typeface is specified for range [" + runStart + ", " + runEnd + ')');
        float typeSize = locator.getTypeSize();
        float sizeByEm = typeSize / typeface.getUnitsPerEm();
        float ascent = typeface.getAscent() * sizeByEm;
        float descent = typeface.getDescent() * sizeByEm;
        float leading = typeface.getLeading() * sizeByEm;
        ReplacementSpan replacement = locator.getReplacement();
        TextRun textRun;
        if (replacement == null) {
            engine.setTypeface(typeface);
            engine.setTypeSize(typeSize);
            ShapingResult shapingResult = null;
            try {
                shapingResult = engine.shapeText(text, runStart, runEnd);
                WritingDirection writingDirection = engine.getWritingDirection();
                boolean isBackward = shapingResult.isBackward();
                int[] glyphIds = shapingResult.getGlyphIds().toArray();
                float[] offsets = shapingResult.getGlyphOffsets().toArray();
                float[] advances = shapingResult.getGlyphAdvances().toArray();
                int[] clusterMap = shapingResult.getClusterMap().toArray();
                FloatList caretEdges = shapingResult.getCaretEdges(null);
                float scaleX = locator.getScaleX();
                if (Float.compare(scaleX, 1.0f) != 0) {
                    for (int i = 0; i < glyphIds.length; i++) {
                        offsets[i * 2] *= scaleX;
                        advances[i] *= scaleX;
                    }
                }
                float baselineShift = locator.getBaselineShift();
                if (Float.compare(baselineShift, 0.0f) != 0) {
                    for (int i = 0; i < glyphIds.length; i++) {
                        offsets[(i * 2) + 1] += baselineShift;
                    }
                }
                textRun = new IntrinsicRun(runStart, runEnd, isBackward, bidiLevel, writingDirection, typeface, typeSize, ascent, descent, leading, glyphIds, offsets, advances, clusterMap, caretEdges);
            } finally {
                if (shapingResult != null) {
                    shapingResult.dispose();
                }
            }
        } else {
            if (paint == null) {
                paint = new Paint();
            }
            if (metrics == null) {
                metrics = new Paint.FontMetricsInt();
            }
            metrics.ascent = (int) -(ascent + 0.5f);
            metrics.descent = (int) (descent + 0.5f);
            metrics.leading = (int) (leading + 0.5f);
            int extent = replacement.getSize(paint, spanned, runStart, runEnd, metrics);
            int runLength = runEnd - runStart;
            float[] caretEdges = new float[runLength + 1];
            if ((bidiLevel & 1) == 0) {
                caretEdges[runLength] = extent;
            } else {
                caretEdges[0] = extent;
            }
            textRun = new ReplacementRun(spanned, runStart, runEnd, bidiLevel, replacement, paint, typeface, typeSize, metrics.ascent, metrics.descent, metrics.leading, extent, FloatList.of(caretEdges));
        }
        runs.add(textRun);
    }
}
Also used : Typeface(com.mta.tehreer.graphics.Typeface) Paint(android.graphics.Paint) ReplacementSpan(android.text.style.ReplacementSpan) ShapingResult(com.mta.tehreer.sfnt.ShapingResult) Paint(android.graphics.Paint) FloatList(com.mta.tehreer.collections.FloatList) WritingDirection(com.mta.tehreer.sfnt.WritingDirection)

Aggregations

FloatList (com.mta.tehreer.collections.FloatList)3 Paint (android.graphics.Paint)1 ReplacementSpan (android.text.style.ReplacementSpan)1 NonNull (androidx.annotation.NonNull)1 IntList (com.mta.tehreer.collections.IntList)1 Typeface (com.mta.tehreer.graphics.Typeface)1 ShapingResult (com.mta.tehreer.sfnt.ShapingResult)1 WritingDirection (com.mta.tehreer.sfnt.WritingDirection)1