ThaiFormatter.java 5.63 KB
/*
 * Decompiled with CFR 0_118.
 */
package com.adobe.fontengine.inlineformatting.infontformatting;

import com.adobe.fontengine.font.FontLoadingException;
import com.adobe.fontengine.font.InvalidFontException;
import com.adobe.fontengine.font.UnsupportedFontException;
import com.adobe.fontengine.font.opentype.OpenTypeFont;
import com.adobe.fontengine.inlineformatting.AttributedRun;
import com.adobe.fontengine.inlineformatting.ElementAttribute;
import com.adobe.fontengine.inlineformatting.infontformatting.GenericFormatter;

final class ThaiFormatter
extends GenericFormatter {
    ThaiFormatter() {
    }

    protected int removeSaraAm(AttributedRun run, int start, int limit) {
        for (int cur = start; cur < limit; ++cur) {
            int usv = run.elementAt(cur);
            if (usv != 3635) continue;
            int prev = cur;
            while (start <= prev - 1 && run.getElementStyle(prev - 1, ElementAttribute.isGlyph) != Boolean.TRUE && 3656 <= run.elementAt(prev - 1) && run.elementAt(prev - 1) <= 3659) {
                --prev;
            }
            if (prev == cur) {
                run.replace(cur, new int[]{3661, 3634});
            } else {
                int[] positions = new int[cur - prev + 1];
                for (int i = 0; i < positions.length; ++i) {
                    positions[i] = prev + i;
                }
                int[] elementIds = new int[cur - prev + 2];
                elementIds[0] = 3661;
                for (int i2 = 1; i2 < elementIds.length - 1; ++i2) {
                    elementIds[i2] = run.elementAt(prev + i2 - 1);
                }
                elementIds[elementIds.length - 1] = 3634;
                run.replace(positions, elementIds);
            }
            ++cur;
            ++limit;
        }
        return limit;
    }

    public int firstPass(AttributedRun run, int start, int limit) {
        limit = this.removeSaraAm(run, start, limit);
        return super.firstPass(run, start, limit);
    }

    protected void shapeTT(AttributedRun run, int start, int limit) {
        boolean OT = false;
        boolean C0 = true;
        int CA = 2;
        int CD = 3;
        int CR = 4;
        int BASE = 5;
        int VA = 6;
        int VB = 7;
        int DA = 8;
        int[] charClass = new int[]{0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 4, 3, 3, 4, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 1, 2, 1, 2, 1, 1, 1, 1, 3, 1, 3, 1, 1, 1, 1, 1, 2, 1, 1, 0, 0, 6, 0, 0, 6, 6, 6, 6, 7, 7, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 8, 8, 8, 8, 8, 8, 8, 0};
        int[] shiftLeft = new int[]{3632, 63248, 3634, 3635, 63233, 63234, 63235, 63236, 3640, 3641, 3642, 3643, 3644, 3645, 3646, 3647, 3648, 3649, 3650, 3651, 3652, 3653, 3654, 63250, 63251, 63252, 63253, 63254, 63255, 63249, 3662, 3663};
        int[] shiftDown = new int[]{3632, 3633, 3634, 3635, 3636, 3637, 3638, 3639, 63256, 63257, 63258, 3643, 3644, 3645, 3646, 3647, 57408, 57409, 57410, 57411, 57412, 57413, 57414, 57415, 63242, 63243, 63244, 63245, 63246, 3661, 3662, 3663};
        int[] shiftLeftAndDown = new int[]{3632, 3633, 3634, 3635, 3636, 3637, 3638, 3639, 3640, 3641, 3642, 3643, 3644, 3645, 3646, 3647, 3648, 3649, 3650, 3651, 3652, 3653, 3654, 3655, 63237, 63238, 63239, 63240, 63241, 3661, 3662, 3663};
        int[] removePieceUnder = new int[]{3584, 3585, 3586, 3587, 3588, 3589, 3590, 3591, 3592, 3593, 3594, 3595, 3596, 63247, 3598, 3599, 63232, 3601, 3602, 3603, 3604, 3605, 3606, 3607, 3608, 3609, 3610, 3611, 3612, 3613, 3614, 3615, 3616, 3617, 3618, 3619, 3620, 3621, 3622, 3623, 3624, 3625, 3626, 3627, 3628, 3629, 3630, 3631};
        int baseIndex = Integer.MIN_VALUE;
        int baseType = 0;
        int baseUsv = -1;
        boolean hasVowelAbove = false;
        while (start < limit) {
            int usv = run.elementAt(start);
            if (usv < 3584 || 3663 < usv) {
                baseIndex = start;
                baseType = 0;
                baseUsv = usv;
                hasVowelAbove = false;
            } else {
                int thisCharClass = charClass[usv - 3584];
                if (thisCharClass <= 5) {
                    baseIndex = start;
                    baseType = thisCharClass;
                    baseUsv = usv;
                    hasVowelAbove = false;
                } else if (thisCharClass == 7) {
                    if (baseType == 4) {
                        run.replace(baseIndex, removePieceUnder[baseUsv - 3584]);
                        baseType = 1;
                    } else if (baseType == 3) {
                        run.replace(start, shiftDown[usv - 3632]);
                    }
                } else if (thisCharClass == 6) {
                    if (baseType == 2) {
                        run.replace(start, shiftLeft[usv - 3632]);
                    }
                    hasVowelAbove = true;
                } else if (thisCharClass == 8) {
                    if (baseType == 2) {
                        if (hasVowelAbove) {
                            run.replace(start, shiftLeft[usv - 3632]);
                        } else {
                            run.replace(start, shiftLeftAndDown[usv - 3632]);
                        }
                    } else if (!hasVowelAbove) {
                        run.replace(start, shiftDown[usv - 3632]);
                    }
                }
            }
            ++start;
        }
    }

    protected boolean canFormatTT() {
        return true;
    }

    protected int formatTT(OpenTypeFont otFont, AttributedRun run, int start, int limit, boolean shouldKern) throws InvalidFontException, UnsupportedFontException, FontLoadingException {
        this.shapeTT(run, start, limit);
        return super.formatTT(otFont, run, start, limit, shouldKern);
    }
}