Properties.java 4.38 KB
/*
 * Decompiled with CFR 0_118.
 */
package com.adobe.fontengine;

import com.adobe.fontengine.UnicodeData;

public final class Properties {
    public static final int MAX_CASE_EXPANSION = 3;
    public static final int CASE_TAILORING_NONE = 0;
    public static final int CASE_TAILORING_DOTTED_I = 1;
    public static final int CASE_TAILORING_SHARP_S = 2;
    public static final int CASE_TAILORING_SUBSCRIPT_IOTA = 4;

    public static int getFullUpperCase(int usv, int tailorings, int[] result) {
        int arg = 0;
        int entry = Properties.searchRangeTable(UnicodeData.caseTable, 9, 19, 399, usv);
        switch (entry >> 29 & 7) {
            case 0: 
            case 5: {
                result[0] = usv;
                return 1;
            }
            case 1: {
                result[0] = usv % 2 == 0 ? usv : usv - 1;
                return 1;
            }
            case 2: {
                result[0] = usv % 2 == 1 ? usv : usv - 1;
                return 1;
            }
            case 3: {
                arg = entry >> 21 & 255;
                result[0] = usv - arg;
                return 1;
            }
            case 4: {
                result[0] = usv - UnicodeData.caseTableDelta[entry >> 21 & 255];
                return 1;
            }
            case 6: {
                arg = entry >> 21 & 255;
                entry = UnicodeData.caseTableComplex[arg];
                if ((entry >> 28 & tailorings) != 0) {
                    entry = UnicodeData.caseTableComplex[arg + 1];
                }
                int cpIndex = entry & 65535;
                int nbUsvs = entry >> 26 & 3;
                if (nbUsvs == 0) {
                    result[0] = usv;
                    return 1;
                }
                for (int i = 0; i < nbUsvs; ++i) {
                    result[i] = UnicodeData.caseTableCp[cpIndex++];
                }
                return nbUsvs;
            }
        }
        return 0;
    }

    public static int getFullLowerCase(int usv, int tailorings, int[] result) {
        int arg = 0;
        int entry = Properties.searchRangeTable(UnicodeData.caseTable, 9, 19, 399, usv);
        switch (entry >> 29 & 7) {
            case 0: 
            case 4: {
                result[0] = usv;
                return 1;
            }
            case 1: {
                result[0] = usv % 2 == 0 ? usv + 1 : usv;
                return 1;
            }
            case 2: {
                result[0] = usv % 2 == 1 ? usv + 1 : usv;
                return 1;
            }
            case 3: {
                arg = entry >> 21 & 255;
                result[0] = usv + 2 - arg;
                return 1;
            }
            case 5: {
                result[0] = usv + UnicodeData.caseTableDelta[entry >> 21 & 255];
                return 1;
            }
            case 6: {
                arg = entry >> 21 & 255;
                entry = UnicodeData.caseTableComplex[arg];
                if ((entry >> 28 & tailorings) != 0) {
                    entry = UnicodeData.caseTableComplex[arg + 1];
                }
                int cpIndex = entry & 65535;
                cpIndex += entry >> 26 & 3;
                cpIndex += entry >> 24 & 3;
                int nbUsvs = entry >> 22 & 3;
                if (nbUsvs == 0) {
                    result[0] = usv;
                    return 1;
                }
                for (int i = 0; i < nbUsvs; ++i) {
                    result[i] = UnicodeData.caseTableCp[cpIndex++];
                }
                return nbUsvs;
            }
        }
        return 0;
    }

    static int searchRangeTable(int[] table, int asciiLimit, int latin1Limit, int unicodeLimit, int usv) {
        int min = 0;
        int max = 0;
        if (usv < 128) {
            min = 0;
            max = asciiLimit;
        } else if (usv < 256) {
            min = asciiLimit - 1;
            max = latin1Limit;
        } else {
            min = latin1Limit - 1;
            max = unicodeLimit;
        }
        while (min < max) {
            int median = (min + max) / 2;
            int u1 = table[median] & 2097151;
            int u2 = table[median + 1] & 2097151;
            if (usv < u1) {
                max = median;
                continue;
            }
            if (u2 <= usv) {
                min = median + 1;
                continue;
            }
            return table[median];
        }
        return 0;
    }
}