UnicodeCmap.java 5.52 KB
/*
 * Decompiled with CFR 0_118.
 */
package com.adobe.fontengine.font.postscript;

import com.adobe.fontengine.CharUtil;
import com.adobe.fontengine.font.InvalidFontException;
import com.adobe.fontengine.font.UnsupportedFontException;
import com.adobe.fontengine.font.opentype.GlyphNames;
import com.adobe.fontengine.font.postscript.CIDtoUnicode;
import com.adobe.fontengine.font.postscript.GlyphNamesAccessor;

public final class UnicodeCmap {
    int[][][] cmap = null;

    public int getGlyphForChar(int usv) throws InvalidFontException, UnsupportedFontException {
        if (usv >> 16 >= this.cmap.length) {
            return -1;
        }
        int[][] c2 = this.cmap[usv >> 16];
        if (c2 == null) {
            return 0;
        }
        int[] c3 = c2[usv >> 8 & 255];
        if (c3 == null) {
            return 0;
        }
        return c3[usv & 255];
    }

    public int getFirstSupportedChar() {
        for (int i = 0; i < this.cmap.length; ++i) {
            if (this.cmap[i] == null) continue;
            for (int j = 0; j < this.cmap[i].length; ++j) {
                if (this.cmap[i][j] == null) continue;
                for (int k = 0; k < this.cmap[i][j].length; ++k) {
                    if (this.cmap[i][j][k] == 0) continue;
                    return i << 16 | j << 8 | k;
                }
            }
        }
        return Integer.MAX_VALUE;
    }

    public int getLastSupportedChar() {
        for (int i = this.cmap.length - 1; i >= 0; --i) {
            if (this.cmap[i] == null) continue;
            for (int j = this.cmap[i].length - 1; j >= 0; --j) {
                if (this.cmap[i][j] == null) continue;
                for (int k = this.cmap[i][j].length - 1; k >= 0; --k) {
                    if (this.cmap[i][j][k] == 0) continue;
                    return i << 16 | j << 8 | k;
                }
            }
        }
        return 0;
    }

    public static UnicodeCmap computeCmapFromGlyphNames(int numGlyphs, boolean isDingbat, GlyphNamesAccessor names) throws InvalidFontException, UnsupportedFontException {
        int[][][] mapping = new int[numGlyphs][][];
        for (int gid = 1; gid < numGlyphs; ++gid) {
            String name = names.getAGlyphName(gid);
            mapping[gid] = UnicodeCmap.characterizeGlyphName(name, isDingbat);
        }
        return UnicodeCmap.buildCmap(mapping);
    }

    private static int[][] characterizeGlyphName(String name, boolean isDingbat) {
        int[][] x;
        int[] usvs = GlyphNames.resolveAGNCNameIntoArray(name, isDingbat);
        int nbUsvs = usvs.length;
        boolean isSuffixed = GlyphNames.getAGNCNameSuffix(name) != null;
        int[] usvs2 = CharUtil.mapStringFrom(usvs, 0, nbUsvs);
        if (usvs2.length == 0) {
            if (nbUsvs == 1) {
                int[][] arrarrn = new int[1][];
                int[] arrn = new int[2];
                arrn[0] = usvs[0];
                arrn[1] = isSuffixed ? 1 : 0;
                arrarrn[0] = arrn;
                x = arrarrn;
            } else {
                x = new int[][]{};
            }
        } else {
            x = new int[usvs2.length][];
            for (int i = 0; i < usvs2.length; ++i) {
                int[] arrn = new int[2];
                arrn[0] = usvs2[i];
                arrn[1] = isSuffixed ? 1 : 0;
                x[i] = arrn;
            }
        }
        return x;
    }

    public static UnicodeCmap computeCmapFromCids(int numGlyphs, GlyphCidAccessor cids, String registry, String ordering) throws InvalidFontException, UnsupportedFontException {
        int[][][] mapping = new int[numGlyphs][][];
        CIDtoUnicode m = CIDtoUnicode.get(registry, ordering);
        for (int gid = 0; gid < numGlyphs; ++gid) {
            int cid = cids.getAGlyphCid(gid);
            mapping[gid] = UnicodeCmap.characterizeCid(m, cid);
        }
        return UnicodeCmap.buildCmap(mapping);
    }

    static int[][] characterizeCid(CIDtoUnicode m, int cid) {
        int usv = m.cid2usv(cid);
        if (usv == -1) {
            return new int[0][];
        }
        return new int[][]{{usv, 0}};
    }

    private static UnicodeCmap buildCmap(int[][][] mapping) {
        UnicodeCmap cmap = new UnicodeCmap();
        cmap.cmap = new int[17][][];
        int[][][] actualPenalties = new int[17][][];
        for (int gid = 1; gid < mapping.length; ++gid) {
            for (int i = 0; i < mapping[gid].length; ++i) {
                int usv = mapping[gid][i][0];
                int penalty = mapping[gid][i][1];
                int plane = usv >> 16;
                int row = usv >> 8 & 255;
                int cell = usv & 255;
                if (cmap.cmap[plane] == null) {
                    cmap.cmap[plane] = new int[256][];
                    actualPenalties[plane] = new int[256][];
                }
                if (cmap.cmap[plane][row] == null) {
                    cmap.cmap[plane][row] = new int[256];
                    actualPenalties[plane][row] = new int[256];
                    for (int c = 0; c < 256; ++c) {
                        cmap.cmap[plane][row][c] = 0;
                        actualPenalties[plane][row][c] = Integer.MAX_VALUE;
                    }
                }
                if (penalty >= actualPenalties[plane][row][cell]) continue;
                cmap.cmap[plane][row][cell] = gid;
                actualPenalties[plane][row][cell] = penalty;
            }
        }
        return cmap;
    }

    public static abstract class GlyphCidAccessor {
        public abstract int getAGlyphCid(int var1) throws InvalidFontException, UnsupportedFontException;
    }

}