com.adobe.xfa.text.DispMap Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of aem-sdk-api Show documentation
Show all versions of aem-sdk-api Show documentation
The Adobe Experience Manager SDK
package com.adobe.xfa.text;
import com.adobe.xfa.ut.Storage;
/**
* @exclude from published api.
*/
class DispMap {
private final Storage moMap = new Storage();
DispMap () {
}
int findItem (int nItemIndex) {
int nMapIndex = search (nItemIndex);
if ((nMapIndex < moMap.size()) && (getItem(nMapIndex).getMapIndex() == nItemIndex)) {
return nMapIndex;
}
while (nMapIndex > 0) {
nMapIndex--;
DispMapItem oItem = getItem (nMapIndex);
if ((nItemIndex >= oItem.getMapIndex())
&& (nItemIndex <= (oItem.getMapIndex() + oItem.getMapLength()))) {
return nMapIndex;
}
}
return moMap.size();
}
boolean isValidMapIndex (int nMapIndex) {
return nMapIndex < moMap.size();
}
int add (DispMapItem delegate, int nIndex, int nLength) {
return add (delegate.cloneMapItem (nIndex, nLength));
}
int add (DispMapItem delegate, int nIndex) {
return add (delegate, nIndex, 1);
}
int add (DispMapItem oAdd) {
int nSlot = moMap.size();
if ((moMap.size() > 0) && (oAdd.getMapIndex() < last().getMapIndex())) {
int nEnd = oAdd.getMapIndex() + oAdd.getMapLength();
nSlot = search (oAdd.getMapIndex());
while (nSlot < moMap.size()) {
int nSlotIndex = getItem(nSlot).getMapIndex();
if (oAdd.getMapIndex() != nSlotIndex) {
break;
}
int nSlotEnd = nSlotIndex + getItem(nSlot).getMapLength();
if (nEnd < nSlotEnd) {
break;
}
nSlot++;
}
}
moMap.add (nSlot, oAdd);
return nSlot;
}
void removeRange (int nCharIndex, int nCharLength /*, SplitFunc pfnSplit */) { // TODO:
// Removes data from a map corresponding to a given character range and
// optionally splits the item containing the removal (it it is contained
// in a single item).
int nMapIndex = findItem (nCharIndex);
if (nMapIndex >= moMap.size()) {
return;
}
// The bStarted flag is to handle the (common) case where the removal
// starts in the middle of a map item. The loop iterates once for each
// item directly affected by the removal.
boolean bStarted = getItem(nMapIndex).getMapIndex() == nCharIndex;
int nLeft = nCharLength;
while (nLeft > 0) {
DispMapItem poItem = getItem (nMapIndex);
int nAvail = poItem.getMapLength();
if (! bStarted) {
nAvail -= nCharIndex - poItem.getMapIndex();
}
int nRemove = nLeft; // how much to remove this time
if (nRemove > nAvail) {
nRemove = nAvail;
}
int nRemaining = poItem.getMapLength() - nRemove;
// If this map item is completely gutted, get rid of it, rather than
// carrying an empty one.
if ((nRemaining == 0) && (moMap.size() > 1)) {
moMap.remove (nMapIndex);
}
else {
// Otherwise, this item still maps to some characters and is the subject
// of a partial removal.
// Removing all it has available: this is removing from the given
// character index to the end of the item. Simply truncate its length.
if (nRemove == nAvail) {
poItem.setMapLength (nRemaining);
}
// If started, we're removing from the start of the item up to the end of
// the removal range. If a split function was provided, use it to
// indicate the removal. Then update the index and length to account for
// the removed characters.
else if (bStarted) {
// if (pfnSplit != null) { // TODO:
// (pfnSplit) (poItem, nRemove);
// }
poItem.setMapIndex (nCharIndex);
poItem.setMapLength (nRemaining);
}
// Otherwise, it is a removal from the middle of an item. If there is no
// split function, simply set its new length to account for the removed
// characters.
else /* if (pfnSplit == null) */ { // TODO:
poItem.setMapLength (nRemaining);
}
// Removal from the middle with a split: Need to create a new item
// corresponding to the second part of the split item, and adjust this
// item's length to just the beginning part. Also increment map index to
// account for the new item created.
// else { // TODO:
// int nBefore = nCharIndex - poItem.getMapIndex();
// int nAfter = nRemaining - nBefore;
// T oSplit (poItem);
// (pfnSplit) (oSplit, nBefore + nRemove);
// Add (oSplit, poItem.getMapIndex() + nBefore, nAfter);
// poItem.setMapLength (nBefore);
// nMapIndex++;
// }
// In all cases where the item isn't removed entirely, need to increment
// the map index (which is used in the subsequent loop), because we're
// done with this item.
nMapIndex++;
}
nLeft -= nRemove;
bStarted = true;
}
// Update the start index of all items that come after those directly
// affected by the removal.
for (; nMapIndex < moMap.size(); nMapIndex++) {
DispMapItem poItem = getItem(nMapIndex);
poItem.setMapIndex (poItem.getMapIndex() - nCharLength);
}
}
void insertMap (DispMap oSourceMap, int nCharIndex, int nCharLength /*, SplitFunc pfnSplit */) { // TODO:
int nMapIndex = findItem (nCharIndex);
if (nMapIndex >= moMap.size()) {
return;
}
int i;
DispMapItem poItem = getItem (nMapIndex);
if (nCharIndex != poItem.getMapIndex()) {
int nSplitFirst = nCharIndex - poItem.getMapIndex();
int nSplitSecond = poItem.getMapLength() - nSplitFirst;
poItem.setMapLength (nSplitFirst);
// if (pfnSplit == null) { // TODO:
add (poItem, nCharIndex, nSplitSecond);
// } else {
// T oNew (poItem);
// (pfnSplit) (oNew, nSplitFirst);
// Add (oNew, nCharIndex, nSplitSecond);
// }
nMapIndex++;
}
for (i = nMapIndex; i < moMap.size(); i++) {
poItem = getItem(i);
poItem.setMapIndex (poItem.getMapIndex() + nCharLength);
}
for (i = 0; i < oSourceMap.size(); i++) {
poItem = oSourceMap.getItem(i);
add (poItem, nCharIndex, poItem.getMapLength());
nCharIndex += poItem.getMapLength();
}
}
void empty () {
moMap.clear();
}
int size () {
return moMap.size();
}
DispMapItem last () {
return getItem (moMap.size() - 1);
}
DispMapItem getItem (int index) {
return moMap.get (index);
}
void preAlloc (int nSize, boolean bPreserve) {
if (nSize > moMap.size()) {
moMap.ensureCapacity (nSize);
}
}
private int search (int nItemIndex) {
int nLow = 0;
int nHigh = moMap.size();
while (nLow < nHigh) {
int nSplit = (nLow + nHigh) / 2;
int nTest = getItem(nSplit).getMapIndex();
if (nItemIndex < nTest) {
nHigh = nSplit;
} else if (nItemIndex > nTest) {
nLow = nSplit + 1;
} else {
nLow = nHigh = nSplit;
}
}
for (; nLow > 0; nLow--) {
if (getItem(nLow-1).getMapIndex() != nItemIndex) {
break;
}
}
return nLow;
}
}
class DispMapSet {
int[] mpcCharData;
int[] mpeBreakData;
int mnCharCount;
int mnCharMax;
DispMap moEmbedMap = new DispMap(); // TODO: could delay creation of embed and glyph loc maps
DispMap moGlyphLocMap = new DispMap();
DispMap moPosnMap = new DispMap();
DispMap moRunMap = new DispMap();
Storage moGlyphs;
DispMapSet () {
}
void clear () {
mnCharCount = 0;
// for (int i = 0; i < moPositionMap.size(); i++) {
// moPositionMap[i].associate (null);
// }
// for (i = 0; i < moRunMap.size(); i++) {
// moRunMap[i].setAttr (null);
// }
moEmbedMap.empty();
moGlyphLocMap.empty();
moPosnMap.empty();
moRunMap.empty();
moGlyphs.clear();
}
int getChar (int nIndex) {
return mpcCharData[nIndex];
}
int[] getCharArray () {
return mpcCharData;
}
int getBreakData (int nIndex) {
return mpeBreakData[nIndex];
}
int[] getBreakArray () {
return mpeBreakData;
}
void addChar (int c, int eData) {
setChar (mnCharCount++, c, eData);
}
void setChar (int nIndex, int c, int eData) {
assert (nIndex < mnCharMax);
mpcCharData[nIndex] = c;
mpeBreakData[nIndex] = eData;
}
void setBreakData (int nIndex, int eData) {
mpeBreakData[nIndex] = eData;
}
void preAllocChars (int nChars, boolean bPreserve) {
if (nChars > mnCharMax) {
int[] newChar = new int [nChars];
int[] newBreak = new int [nChars];
if (bPreserve) {
for (int i = 0; i < mnCharCount; i++) {
newChar[i] = mpcCharData[i];
newBreak[i] = mpeBreakData[i];
}
}
mpcCharData = newChar;
mpeBreakData = newBreak;
mnCharMax = nChars;
}
if (bPreserve) {
mnCharCount = nChars;
} else {
mnCharCount = 0;
}
}
void preAllocChars (int nChars) {
preAllocChars (nChars, false);
}
Glyph getGlyph (int index) {
return moGlyphs.get (index);
}
int getEmbedCount () {
return moEmbedMap.size();
}
DispEmbed getEmbed (int index) {
return (DispEmbed) moEmbedMap.getItem (index);
}
int getGlyphLocCount () {
return moGlyphLocMap.size();
}
GlyphLoc getGlyphLoc (int index) {
return (GlyphLoc) moGlyphLocMap.getItem (index);
}
void preAllocGlyphs (int nGlyphs, boolean bAllocGlyphLocs, boolean bPreserve) {
if (moGlyphs == null) {
moGlyphs = new Storage();
}
moGlyphs.ensureCapacity (nGlyphs);
if (bAllocGlyphLocs) {
moGlyphLocMap.preAlloc (nGlyphs, bPreserve);
}
}
void preAllocGlyphs (int nGlyphs, boolean bAllocGlyphLocs) {
preAllocGlyphs (nGlyphs, bAllocGlyphLocs, false);
}
int getPositionCount () {
return moPosnMap.size();
}
DispPosn getPosition (int index) {
return (DispPosn) moPosnMap.getItem (index);
}
int getRunCount () {
return moRunMap.size();
}
DispRun getRun (int index) {
return (DispRun) moRunMap.getItem (index);
}
}
© 2015 - 2024 Weber Informatics LLC | Privacy Policy