DispMap.java 5.16 KB
/*
 * Decompiled with CFR 0_118.
 */
package com.adobe.xfa.text;

import com.adobe.xfa.text.DispMapItem;
import com.adobe.xfa.ut.Storage;

class DispMap {
    private final Storage<DispMapItem> moMap = new Storage();

    DispMap() {
    }

    int findItem(int nItemIndex) {
        int nMapIndex = this.search(nItemIndex);
        if (nMapIndex < this.moMap.size() && this.getItem(nMapIndex).getMapIndex() == nItemIndex) {
            return nMapIndex;
        }
        while (nMapIndex > 0) {
            DispMapItem oItem;
            if (nItemIndex < (oItem = this.getItem(--nMapIndex)).getMapIndex() || nItemIndex > oItem.getMapIndex() + oItem.getMapLength()) continue;
            return nMapIndex;
        }
        return this.moMap.size();
    }

    boolean isValidMapIndex(int nMapIndex) {
        return nMapIndex < this.moMap.size();
    }

    int add(DispMapItem delegate, int nIndex, int nLength) {
        return this.add(delegate.cloneMapItem(nIndex, nLength));
    }

    int add(DispMapItem delegate, int nIndex) {
        return this.add(delegate, nIndex, 1);
    }

    int add(DispMapItem oAdd) {
        int nSlot = this.moMap.size();
        if (this.moMap.size() > 0 && oAdd.getMapIndex() < this.last().getMapIndex()) {
            int nEnd = oAdd.getMapIndex() + oAdd.getMapLength();
            for (nSlot = this.search((int)oAdd.getMapIndex()); nSlot < this.moMap.size(); ++nSlot) {
                int nSlotEnd;
                int nSlotIndex = this.getItem(nSlot).getMapIndex();
                if (oAdd.getMapIndex() != nSlotIndex || nEnd < (nSlotEnd = nSlotIndex + this.getItem(nSlot).getMapLength())) break;
            }
        }
        this.moMap.add(nSlot, oAdd);
        return nSlot;
    }

    void removeRange(int nCharIndex, int nCharLength) {
        DispMapItem poItem;
        int nRemove;
        int nMapIndex = this.findItem(nCharIndex);
        if (nMapIndex >= this.moMap.size()) {
            return;
        }
        boolean bStarted = this.getItem(nMapIndex).getMapIndex() == nCharIndex;
        for (int nLeft = nCharLength; nLeft > 0; nLeft -= nRemove) {
            int nRemaining;
            poItem = this.getItem(nMapIndex);
            int nAvail = poItem.getMapLength();
            if (!bStarted) {
                nAvail -= nCharIndex - poItem.getMapIndex();
            }
            if ((nRemove = nLeft) > nAvail) {
                nRemove = nAvail;
            }
            if ((nRemaining = poItem.getMapLength() - nRemove) == 0 && this.moMap.size() > 1) {
                this.moMap.remove(nMapIndex);
            } else {
                if (nRemove == nAvail) {
                    poItem.setMapLength(nRemaining);
                } else if (bStarted) {
                    poItem.setMapIndex(nCharIndex);
                    poItem.setMapLength(nRemaining);
                } else {
                    poItem.setMapLength(nRemaining);
                }
                ++nMapIndex;
            }
            bStarted = true;
        }
        while (nMapIndex < this.moMap.size()) {
            poItem = this.getItem(nMapIndex);
            poItem.setMapIndex(poItem.getMapIndex() - nCharLength);
            ++nMapIndex;
        }
    }

    void insertMap(DispMap oSourceMap, int nCharIndex, int nCharLength) {
        int i;
        int nMapIndex = this.findItem(nCharIndex);
        if (nMapIndex >= this.moMap.size()) {
            return;
        }
        DispMapItem poItem = this.getItem(nMapIndex);
        if (nCharIndex != poItem.getMapIndex()) {
            int nSplitFirst = nCharIndex - poItem.getMapIndex();
            int nSplitSecond = poItem.getMapLength() - nSplitFirst;
            poItem.setMapLength(nSplitFirst);
            this.add(poItem, nCharIndex, nSplitSecond);
            ++nMapIndex;
        }
        for (i = nMapIndex; i < this.moMap.size(); ++i) {
            poItem = this.getItem(i);
            poItem.setMapIndex(poItem.getMapIndex() + nCharLength);
        }
        for (i = 0; i < oSourceMap.size(); ++i) {
            poItem = oSourceMap.getItem(i);
            this.add(poItem, nCharIndex, poItem.getMapLength());
            nCharIndex += poItem.getMapLength();
        }
    }

    void empty() {
        this.moMap.clear();
    }

    int size() {
        return this.moMap.size();
    }

    DispMapItem last() {
        return this.getItem(this.moMap.size() - 1);
    }

    DispMapItem getItem(int index) {
        return this.moMap.get(index);
    }

    void preAlloc(int nSize, boolean bPreserve) {
        if (nSize > this.moMap.size()) {
            this.moMap.ensureCapacity(nSize);
        }
    }

    private int search(int nItemIndex) {
        int nLow = 0;
        int nHigh = this.moMap.size();
        while (nLow < nHigh) {
            int nSplit = (nLow + nHigh) / 2;
            int nTest = this.getItem(nSplit).getMapIndex();
            if (nItemIndex < nTest) {
                nHigh = nSplit;
                continue;
            }
            if (nItemIndex > nTest) {
                nLow = nSplit + 1;
                continue;
            }
            nLow = nHigh = nSplit;
        }
        while (nLow > 0 && this.getItem(nLow - 1).getMapIndex() == nItemIndex) {
            --nLow;
        }
        return nLow;
    }
}