TibetanFormatter.java 8.82 KB
/*
 * Decompiled with CFR 0_118.
 * 
 * Could not load the following classes:
 *  com.adobe.agl.lang.UCharacter
 *  com.adobe.agl.util.ULocale
 */
package com.adobe.fontengine.inlineformatting.infontformatting;

import com.adobe.agl.lang.UCharacter;
import com.adobe.agl.util.ULocale;
import com.adobe.fontengine.CharUtil;
import com.adobe.fontengine.font.FontData;
import com.adobe.fontengine.font.FontLoadingException;
import com.adobe.fontengine.font.InvalidFontException;
import com.adobe.fontengine.font.UnsupportedFontException;
import com.adobe.fontengine.font.opentype.Gdef;
import com.adobe.fontengine.font.opentype.Gpos;
import com.adobe.fontengine.font.opentype.Gsub;
import com.adobe.fontengine.font.opentype.OTSelector;
import com.adobe.fontengine.font.opentype.OTSelectors;
import com.adobe.fontengine.font.opentype.OpenTypeFont;
import com.adobe.fontengine.font.opentype.Tag;
import com.adobe.fontengine.inlineformatting.AttributedRun;
import com.adobe.fontengine.inlineformatting.ElementAttribute;
import com.adobe.fontengine.inlineformatting.infontformatting.GenericFormatter;
import com.adobe.fontengine.inlineformatting.infontformatting.InFontFormatter;
import com.adobe.fontengine.inlineformatting.infontformatting.LookupsCache;

public final class TibetanFormatter
extends GenericFormatter {
    public static final int[] u0f73 = new int[]{3953, 3954};
    public static final int[] u0f75 = new int[]{3953, 3956};
    public static final int[] u0f76 = new int[]{4018, 3968};
    public static final int[] u0f77 = new int[]{4018, 3953, 3968};
    public static final int[] u0f78 = new int[]{4019, 3968};
    public static final int[] u0f79 = new int[]{4019, 3953, 3968};
    public static final int[] u0f81 = new int[]{3953, 3968};
    protected static final int[] order = new int[]{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 9, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 6, 0, 4, 0, 0, 0, 0, 0, 6, 6, 6, 6, 6, 9, 6, 0, 7, 7, 5, 0, 8, 8, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
    private static final int[] gsubFeatures = new int[]{Tag.feature_ccmp, Tag.feature_locl, Tag.feature_blws, Tag.feature_abvs};
    private static final int[] gposFeatures = new int[]{Tag.feature_blwm, Tag.feature_abvm, Tag.feature_kern};

    protected int splitComposites(AttributedRun run, int start, int limit) {
        block9 : while (start < limit) {
            int usv = run.elementAt(start);
            switch (usv) {
                case 3955: {
                    run.replace(start, u0f73);
                    limit += u0f73.length - 1;
                    start += u0f73.length;
                    continue block9;
                }
                case 3957: {
                    run.replace(start, u0f75);
                    limit += u0f75.length - 1;
                    start += u0f75.length;
                    continue block9;
                }
                case 3958: {
                    run.replace(start, u0f76);
                    limit += u0f76.length - 1;
                    start += u0f76.length;
                    continue block9;
                }
                case 3959: {
                    run.replace(start, u0f77);
                    limit += u0f77.length - 1;
                    start += u0f77.length;
                    continue block9;
                }
                case 3960: {
                    run.replace(start, u0f78);
                    limit += u0f78.length - 1;
                    start += u0f78.length;
                    continue block9;
                }
                case 3961: {
                    run.replace(start, u0f79);
                    limit += u0f79.length - 1;
                    start += u0f79.length;
                    continue block9;
                }
                case 3969: {
                    run.replace(start, u0f81);
                    limit += u0f81.length - 1;
                    start += u0f81.length;
                    continue block9;
                }
            }
            ++start;
        }
        return limit;
    }

    protected int getOrder(int usv) {
        if (usv < 3840 || usv > 4080) {
            return 0;
        }
        return order[usv - 3840];
    }

    protected void processOneStack(AttributedRun run, int start, int limit, OpenTypeFont otFont) throws InvalidFontException, UnsupportedFontException {
        if (limit - start <= 2) {
            for (int i = start; i < limit; ++i) {
                run.replace(i, otFont.getGlyphForChar(run.elementAt(i)));
                run.setElementStyle(i, ElementAttribute.isGlyph, Boolean.TRUE);
            }
            return;
        }
        int[] stack = new int[limit - start];
        int[] positions = new int[limit - start];
        int i = start;
        while (i < limit) {
            stack[i - start] = run.elementAt(i);
            positions[i - start] = i++;
        }
        for (i = 1; i < stack.length - 1; ++i) {
            for (int j = stack.length - 1; j > i; --j) {
                if (this.getOrder(stack[j - 1]) <= this.getOrder(stack[j])) continue;
                int temp = stack[j];
                stack[j] = stack[j - 1];
                stack[j - 1] = temp;
            }
        }
        for (i = 0; i < stack.length; ++i) {
            stack[i] = otFont.getGlyphForChar(stack[i]);
        }
        run.replace(positions, stack);
        run.setElementStyle(start, limit, ElementAttribute.isGlyph, Boolean.TRUE);
    }

    protected int processStacks(AttributedRun run, int start, int limit, OpenTypeFont otFont) throws InvalidFontException, UnsupportedFontException {
        while (start < limit) {
            if (run.getElementStyle(start, ElementAttribute.isGlyph) == Boolean.TRUE) {
                ++start;
                continue;
            }
            int usv = run.elementAt(start);
            if (CharUtil.isControl(usv)) {
                run.remove(start);
                --limit;
                continue;
            }
            if ((Integer)run.getElementStyle(start, ElementAttribute.bidiLevel) % 2 == 1) {
                usv = UCharacter.getMirror((int)usv);
            }
            int stackStart = start++;
            while (start < limit && CharUtil.isCombining(run.elementAt(start))) {
                ++start;
            }
            this.processOneStack(run, stackStart, start, otFont);
        }
        return limit;
    }

    protected boolean canFormatOT() {
        return true;
    }

    protected int formatOT(OpenTypeFont otFont, AttributedRun run, int start, int limit, boolean shouldKern) throws InvalidFontException, UnsupportedFontException, FontLoadingException {
        int scriptTag = TibetanFormatter.getOTScriptTag((Integer)run.getElementStyle(start, InFontFormatter.scriptAttribute));
        int langTag = TibetanFormatter.getOTLanguageTag((ULocale)run.getElementStyle(start, ElementAttribute.locale));
        limit = this.splitComposites(run, start, limit);
        limit = this.processStacks(run, start, limit, otFont);
        if (otFont.gsub != null) {
            int[][] gsubLookups = LookupsCache.resolveFeatureTag(otFont.gsub, scriptTag, langTag, gsubFeatures);
            limit = otFont.gsub.applyLookups(gsubLookups[0], run, start, limit, OTSelectors.everywhere, otFont.gdef);
            limit = otFont.gsub.applyLookups(gsubLookups[1], run, start, limit, OTSelectors.everywhere, otFont.gdef);
            limit = otFont.gsub.applyLookups(gsubLookups[2], run, start, limit, OTSelectors.everywhere, otFont.gdef);
            limit = otFont.gsub.applyLookups(gsubLookups[3], run, start, limit, OTSelectors.everywhere, otFont.gdef);
        }
        this.posFromAdvanceWidth(run, otFont, start, limit);
        if (otFont.gpos != null) {
            int[][] gposLookups = LookupsCache.resolveFeatureTag(otFont.gpos, scriptTag, langTag, gposFeatures);
            limit = otFont.gpos.applyLookups(gposLookups[0], run, start, limit, OTSelectors.everywhere, otFont.gdef);
            limit = otFont.gpos.applyLookups(gposLookups[1], run, start, limit, OTSelectors.everywhere, otFont.gdef);
            if (shouldKern) {
                if (gposLookups[2].length != 0) {
                    limit = otFont.gpos.applyLookups(gposLookups[2], run, start, limit, OTSelectors.everywhere, otFont.gdef);
                }
            } else {
                this.applyKernTable(otFont, run, start, limit);
            }
        }
        return limit;
    }
}