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:
Nick Burch 2005-11-13 13:28:34 +00:00
parent 67901ee8f9
commit cf4e00a052
2 changed files with 70 additions and 21 deletions

View File

@ -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();
while(cStyles.size() > 1) { cStyles.removeLast(); } LinkedList cStyles = _styleAtom.getCharacterStyles();
while(cStyles.size() > 1) { cStyles.removeLast(); }
TextPropCollection pCol = (TextPropCollection)pStyles.getFirst();
TextPropCollection cCol = (TextPropCollection)cStyles.getFirst(); TextPropCollection pCol = (TextPropCollection)pStyles.getFirst();
pCol.updateTextSize(s.length()); TextPropCollection cCol = (TextPropCollection)cStyles.getFirst();
cCol.updateTextSize(s.length()); pCol.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];

View File

@ -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