com.adobe.xfa.text.TextContext Maven / Gradle / Ivy
Show all versions of aem-sdk-api Show documentation
package com.adobe.xfa.text;
import java.io.FileWriter;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import com.adobe.xfa.gfx.GFXMappingList;
import com.adobe.xfa.ut.FindBugsSuppress;
import com.adobe.xfa.ut.LcLocale;
/**
* The text context exists to allow multiple text displays to share
* instances of formatting-related objects. Many of these objects are
* expensive to create and destroy, but are serially reusable. By
* sharing them amongst text displays, we can amortize the cost of their
* creation over many such displays. Note that this sharing is not
* thread-safe; there must be a separate text context for each thread.
*
* The text context is opaque; it has no client-callable methods other
* than constructor and destructor. The client simply has to create one
* and pass it to each displayable stream through the stream's
* SetContext() method.
*
*
* @exclude from published api.
*/
public class TextContext {
private static final int BREAK_CANDIDATE_MIN = 100;
private DispMapSet mpoDisposableMaps;
private boolean mbMapsCheckedOut;
private boolean[] moBreakCandidates;
private final Map moLocalePool = new HashMap();
private final TextIntArray moAccentRun = new TextIntArray();
private final TextIntArray moGlyphArray = new TextIntArray();
private GFXMappingList mpoMappingList;
// private AXTELang mpoAXTELang;
private MappingManager mMappingManager;
private AFEAttrMap mAFEAttrMap;
@FindBugsSuppress(code="UwF") // will never be written as long as gEnableDebug == false
private FileWriter mDebugFile;
private final static boolean gEnableDebug = false;
/**
* Constructor.
*
* Create an initially unassociated text context. The caller can then
* associate this context with text streams.
*/
public TextContext () {
mAFEAttrMap = new AFEAttrMap (this);
if (gEnableDebug) {
try {
mDebugFile = new FileWriter ("c:/temp/axte-java.log");
} catch (IOException e) {
}
}
}
public void detach () {
if (mDebugFile != null) {
try {
mDebugFile.write (mAFEAttrMap.toString());
mDebugFile.write ('\n');
} catch (IOException e) {
}
try {
mDebugFile.close();
} catch (IOException e) {
}
}
}
/**
* Get a pointer to the current AXTE language processing object for this
* context.
* @return Pointer to the current AXTE language processing object. May
* be null if no such object has been set or inferred. Note that the
* call does not increment the reference count on the object; the caller
* must do that if it intends to hang on to the pointer.
*/
// public AXTELang getAXTELang () {
// return mpoAXTELang;
// }
/**
* Set the AXTE language processing object.
* @Description
* Allows the caller to cache a pointer to its own AXTE language
* processing object in this context. This allows the caller and AXTE
* to share the same object instance. The context will maintain its own
* reference count on the given object. Note that layout operations may
* cause the context to infer an AXTE language processing object if none
* has been set by the caller. In other words, if the caller wishes to
* set one, it should do so before performing layout.
* @param poAXTELang - Pointer to AXTE language processing object to be
* used by this context.
*/
// public void setAXTELang (AXTELang poAXTELang) {
// mpoAXTELang.attach (poAXTELang);
// }
LocaleInfo lookupLocale (String sLocaleName) {
LocaleInfo oLocaleInfo = moLocalePool.get (sLocaleName);
if (oLocaleInfo != null)
return oLocaleInfo;
LcLocale poLocale = new LcLocale (sLocaleName);
oLocaleInfo = new LocaleInfo(
poLocale,
poLocale.isBIDI(),
poLocale.isIdeographic(),
poLocale.needsDictionaryBreaking(),
TextAttr.DIGITS_ARABIC); // TBD: base on locale
moLocalePool.put (sLocaleName, oLocaleInfo);
return oLocaleInfo;
}
DispMapSet getDisposableMaps () {
if (mpoDisposableMaps == null) {
mpoDisposableMaps = new DispMapSet();
}
if (mbMapsCheckedOut) {
return new DispMapSet();
} else {
mbMapsCheckedOut = true;
return mpoDisposableMaps;
}
}
void releaseDisposableMaps (DispMapSet poMaps) {
if (poMaps == mpoDisposableMaps) { // TODO: currently keep only one set around
mbMapsCheckedOut = false;
}
}
boolean[] getBreakCandidates (int nCount, int nPreserve) {
if (nCount < BREAK_CANDIDATE_MIN) {
nCount = BREAK_CANDIDATE_MIN;
}
if (moBreakCandidates == null) {
assert (nPreserve == 0);
moBreakCandidates = new boolean [nCount];
} else if (nCount > moBreakCandidates.length) {
assert (nPreserve <= moBreakCandidates.length);
boolean[] newCandidates = new boolean [nCount];
for (int i = 0; i < nPreserve; i++) {
newCandidates[i] = moBreakCandidates[i];
}
moBreakCandidates = newCandidates;
}
return moBreakCandidates;
}
int[] getAccentRun (int size) {
return moAccentRun.setSize (size, true);
}
int[] getGlyphArray () {
return moGlyphArray.getArray();
}
int[] getGlyphArray (int size) {
return moGlyphArray.setSize (size, true);
}
GFXMappingList getMappingList () {
if (mpoMappingList == null) {
mpoMappingList = new GFXMappingList();
}
return mpoMappingList;
}
DispLineWrapped allocateWrappedLine (TextFrame poFrame, LineDesc oLineDesc) {
// DispLineWrapped poLine;
//
// poLine = new DispLineWrapped;
// if (moLinePool.getSize() > 0) {
// poLine = moLinePool.last();
// moLinePool.removeLast();
// } else {
// poLine = new DispLineWrapped;
// }
// poLine.initialize (poFrame, oLineDesc);
//
// return poLine;
DispLineWrapped poLine = new DispLineWrapped(); // TODO: not convinced there's a need to pool lines in Java
poLine.initialize(poFrame, oLineDesc);
return poLine;
}
void releaseWrappedLine (DispLineWrapped poLine) {
// poLine.clear();
// delete poLine;
// moLinePool.add (poLine);
}
// AXTELang forceAXTELang () {
// if (mpoAXTELang == null) {
// mpoAXTELang = AXTELang.createInstance();
// }
// return mpoAXTELang.returnPtr();
// }
MappingManager getMappingManager () {
if (mMappingManager == null) {
mMappingManager = new MappingManager();
}
return mMappingManager;
}
AFEAttrMap getAFEAttrMap () {
return mAFEAttrMap;
}
boolean debug () {
return mDebugFile != null;
}
void debug (String data) {
if (mDebugFile != null) {
try {
mDebugFile.write (data);
mDebugFile.write ('\n');
} catch (IOException e) {
}
}
}
}