Handle saving unicode text where the underlying record was byte based, by
swapping the record git-svn-id: https://svn.apache.org/repos/asf/jakarta/poi/trunk@353792 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
67901ee8f9
commit
cf4e00a052
@ -36,12 +36,14 @@ import org.apache.poi.util.StringUtil;
|
|||||||
|
|
||||||
public class TextRun
|
public class TextRun
|
||||||
{
|
{
|
||||||
private TextHeaderAtom _headerAtom;
|
// Note: These fields are protected to help with unit testing
|
||||||
private TextBytesAtom _byteAtom;
|
// Other classes shouldn't really go playing with them!
|
||||||
private TextCharsAtom _charAtom;
|
protected TextHeaderAtom _headerAtom;
|
||||||
private StyleTextPropAtom _styleAtom;
|
protected TextBytesAtom _byteAtom;
|
||||||
private boolean _isUnicode;
|
protected TextCharsAtom _charAtom;
|
||||||
private RichTextRun[] _rtRuns;
|
protected StyleTextPropAtom _styleAtom;
|
||||||
|
protected boolean _isUnicode;
|
||||||
|
protected RichTextRun[] _rtRuns;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructs a Text Run from a Unicode text block
|
* Constructs a Text Run from a Unicode text block
|
||||||
@ -101,6 +103,13 @@ public class TextRun
|
|||||||
* Saves the given string to the records. Doesn't touch the stylings.
|
* Saves the given string to the records. Doesn't touch the stylings.
|
||||||
*/
|
*/
|
||||||
private void storeText(String s) {
|
private void storeText(String s) {
|
||||||
|
// Remove a single trailing \n, as there is an implicit one at the
|
||||||
|
// end of every record
|
||||||
|
if(s.endsWith("\n")) {
|
||||||
|
s = s.substring(0, s.length()-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Store in the appropriate record
|
||||||
if(_isUnicode) {
|
if(_isUnicode) {
|
||||||
// The atom can safely convert to unicode
|
// The atom can safely convert to unicode
|
||||||
_charAtom.setText(s);
|
_charAtom.setText(s);
|
||||||
@ -113,7 +122,27 @@ public class TextRun
|
|||||||
StringUtil.putCompressedUnicode(s,text,0);
|
StringUtil.putCompressedUnicode(s,text,0);
|
||||||
_byteAtom.setText(text);
|
_byteAtom.setText(text);
|
||||||
} else {
|
} else {
|
||||||
throw new RuntimeException("Setting of unicode text is currently only possible for Text Runs that are Unicode in the file, sorry. For now, please convert that text to us-ascii and re-try it");
|
// Need to swap a TextBytesAtom for a TextCharsAtom
|
||||||
|
|
||||||
|
// Build the new TextCharsAtom
|
||||||
|
_charAtom = new TextCharsAtom();
|
||||||
|
_charAtom.setText(s);
|
||||||
|
|
||||||
|
// Use the TextHeaderAtom to do the swap on the parent
|
||||||
|
RecordContainer parent = _headerAtom.getParentRecord();
|
||||||
|
Record[] cr = parent.getChildRecords();
|
||||||
|
for(int i=0; i<cr.length; i++) {
|
||||||
|
// Look for TextBytesAtom
|
||||||
|
if(cr[i].equals(_byteAtom)) {
|
||||||
|
// Found it, so replace, then all done
|
||||||
|
cr[i] = _charAtom;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Flag the change
|
||||||
|
_byteAtom = null;
|
||||||
|
_isUnicode = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -151,19 +180,25 @@ public class TextRun
|
|||||||
// The building relies on the old text still being present
|
// The building relies on the old text still being present
|
||||||
StringBuffer newText = new StringBuffer();
|
StringBuffer newText = new StringBuffer();
|
||||||
for(int i=0; i<_rtRuns.length; i++) {
|
for(int i=0; i<_rtRuns.length; i++) {
|
||||||
// Update start position
|
// Do we need to update the start position of this run?
|
||||||
if(i > runID) {
|
if(i <= runID) {
|
||||||
|
// Change is after this, so don't need to change start position
|
||||||
|
} else {
|
||||||
|
// Change has occured, so update start position
|
||||||
_rtRuns[i].updateStartPosition(newText.length());
|
_rtRuns[i].updateStartPosition(newText.length());
|
||||||
}
|
}
|
||||||
// Grab new text
|
|
||||||
|
// Build up the new text
|
||||||
if(i != runID) {
|
if(i != runID) {
|
||||||
|
// Not the affected run, so keep old text
|
||||||
newText.append(_rtRuns[i].getRawText());
|
newText.append(_rtRuns[i].getRawText());
|
||||||
} else {
|
} else {
|
||||||
|
// Affected run, so use new text
|
||||||
newText.append(s);
|
newText.append(s);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Save the new text
|
// Now we can save the new text
|
||||||
storeText(newText.toString());
|
storeText(newText.toString());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -177,17 +212,22 @@ public class TextRun
|
|||||||
storeText(s);
|
storeText(s);
|
||||||
|
|
||||||
// Now handle record stylings:
|
// Now handle record stylings:
|
||||||
|
// If there isn't styling
|
||||||
|
// no change, stays with no styling
|
||||||
|
// If there is styling:
|
||||||
// everthing gets the same style that the first block has
|
// everthing gets the same style that the first block has
|
||||||
LinkedList pStyles = _styleAtom.getParagraphStyles();
|
if(_styleAtom != null) {
|
||||||
while(pStyles.size() > 1) { pStyles.removeLast(); }
|
LinkedList pStyles = _styleAtom.getParagraphStyles();
|
||||||
|
while(pStyles.size() > 1) { pStyles.removeLast(); }
|
||||||
|
|
||||||
LinkedList cStyles = _styleAtom.getCharacterStyles();
|
LinkedList cStyles = _styleAtom.getCharacterStyles();
|
||||||
while(cStyles.size() > 1) { cStyles.removeLast(); }
|
while(cStyles.size() > 1) { cStyles.removeLast(); }
|
||||||
|
|
||||||
TextPropCollection pCol = (TextPropCollection)pStyles.getFirst();
|
TextPropCollection pCol = (TextPropCollection)pStyles.getFirst();
|
||||||
TextPropCollection cCol = (TextPropCollection)cStyles.getFirst();
|
TextPropCollection cCol = (TextPropCollection)cStyles.getFirst();
|
||||||
pCol.updateTextSize(s.length());
|
pCol.updateTextSize(s.length());
|
||||||
cCol.updateTextSize(s.length());
|
cCol.updateTextSize(s.length());
|
||||||
|
}
|
||||||
|
|
||||||
// Finally, zap and re-do the RichTextRuns
|
// Finally, zap and re-do the RichTextRuns
|
||||||
_rtRuns = new RichTextRun[1];
|
_rtRuns = new RichTextRun[1];
|
||||||
|
@ -71,6 +71,15 @@ public class TextCharsAtom extends RecordAtom
|
|||||||
_text = new byte[len-8];
|
_text = new byte[len-8];
|
||||||
System.arraycopy(source,start+8,_text,0,len-8);
|
System.arraycopy(source,start+8,_text,0,len-8);
|
||||||
}
|
}
|
||||||
|
/**
|
||||||
|
* Create an empty TextCharsAtom
|
||||||
|
*/
|
||||||
|
public TextCharsAtom() {
|
||||||
|
// 0 length header
|
||||||
|
_header = new byte[] { 0, 0, 0xA0-256, 0x0f, 0, 0, 0, 0 };
|
||||||
|
// Empty text
|
||||||
|
_text = new byte[0];
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* We are of type 4000
|
* We are of type 4000
|
||||||
|
Loading…
Reference in New Issue
Block a user