1 16 17 package org.apache.poi.hssf.record; 18 19 import org.apache.poi.hssf.usermodel.HSSFRichTextString; 20 import org.apache.poi.util.StringUtil; 21 import org.apache.poi.util.LittleEndian; 22 import org.apache.poi.util.HexDump; 23 import java.io.UnsupportedEncodingException ; 24 25 public class TextObjectRecord 26 extends TextObjectBaseRecord 27 { 28 HSSFRichTextString str = new HSSFRichTextString( "" ); 29 int continueRecordCount = 0; 31 public TextObjectRecord() 32 { 33 } 34 35 public TextObjectRecord( short id, short size, byte[] data ) 36 { 37 super( id, size, data ); 38 } 39 40 public TextObjectRecord( short id, short size, byte[] data, int offset ) 41 { 42 super( id, size, data, offset ); 43 } 44 45 public int getRecordSize() 46 { 47 int continue1Size = 0; 48 int continue2Size = 0; 49 if (str.length() != 0) 50 { 51 continue1Size = str.length() * 2 + 1 + 4; 52 continue2Size = (str.numFormattingRuns() + 1) * 8 + 4; 53 } 54 return super.getRecordSize() + continue1Size + continue2Size; 55 } 56 57 public int serialize( int offset, byte[] data ) 58 { 59 HSSFRichTextString temp = str; 61 str = new HSSFRichTextString(""); 62 int bytesWritten1 = super.serialize( offset, data ); 63 str = temp; 64 65 int pos = offset + bytesWritten1; 66 if ( str.toString().equals( "" ) == false ) 67 { 68 ContinueRecord c1 = createContinue1(); 69 ContinueRecord c2 = createContinue2(); 70 int bytesWritten2 = c1.serialize( pos, data ); 71 pos += bytesWritten2; 72 int bytesWritten3 = c2.serialize( pos, data ); 73 pos += bytesWritten3; 74 75 int size = bytesWritten1 + bytesWritten2 + bytesWritten3; 76 if ( size != getRecordSize() ) 77 throw new RecordFormatException(size + " bytes written but getRecordSize() reports " + getRecordSize()); 78 return size; 79 } 80 if ( bytesWritten1 != getRecordSize() ) 81 throw new RecordFormatException(bytesWritten1 + " bytes written but getRecordSize() reports " + getRecordSize()); 82 return bytesWritten1; 83 } 84 85 private ContinueRecord createContinue1() 86 { 87 ContinueRecord c1 = new ContinueRecord(); 88 byte[] c1Data = new byte[str.length() * 2 + 1]; 89 try 90 { 91 c1Data[0] = 1; 92 System.arraycopy( str.toString().getBytes( "UTF-16LE" ), 0, c1Data, 1, str.length() * 2 ); 93 } 94 catch ( UnsupportedEncodingException e ) 95 { 96 throw new RuntimeException ( e.getMessage() ); 97 } 98 c1.setData( c1Data ); 99 return c1; 100 } 101 102 private ContinueRecord createContinue2() 103 { 104 ContinueRecord c2 = new ContinueRecord(); 105 byte[] c2Data = new byte[str.numFormattingRuns() * 8 + 8]; 106 int pos = 0; 107 for ( int i = 0; i < str.numFormattingRuns(); i++ ) 108 { 109 LittleEndian.putShort( c2Data, pos, (short) str.getIndexOfFormattingRun( i ) ); 110 pos += 2; 111 LittleEndian.putShort( c2Data, pos, str.getFontOfFormattingRun( i ) == str.NO_FONT ? 0 : str.getFontOfFormattingRun( i ) ); 112 pos += 2; 113 pos += 4; } 115 LittleEndian.putShort( c2Data, pos, (short) str.length() ); 116 pos += 2; 117 LittleEndian.putShort( c2Data, pos, (short) 0 ); 118 pos += 2; 119 pos += 4; 121 c2.setData( c2Data ); 122 123 return c2; 124 } 125 126 public void processContinueRecord( byte[] data ) 127 { 128 if ( continueRecordCount == 0 ) 129 processRawString( data ); 130 else 131 processFontRuns( data ); 132 continueRecordCount++; 133 } 134 135 private void processFontRuns( byte[] data ) 136 { 137 int pos = 0; 138 do 139 { 140 short index = LittleEndian.getShort( data, pos ); 141 pos += 2; 142 short iFont = LittleEndian.getShort( data, pos ); 143 pos += 2; 144 pos += 4; 146 if ( index >= str.length() ) 147 break; 148 str.applyFont( index, str.length(), iFont ); 149 } 150 while ( true ); 151 } 152 153 private void processRawString( byte[] data ) 154 { 155 String s; 156 int pos = 0; 157 byte compressByte = data[pos++]; 158 boolean isCompressed = compressByte == 0; 159 try 160 { 161 if ( isCompressed ) 162 { 163 s = new String ( data, pos, getTextLength(), StringUtil.getPreferredEncoding() ); 164 } 165 else 166 { 167 s = new String ( data, pos, getTextLength() * 2, "UTF-16LE" ); 168 } 169 } 170 catch ( UnsupportedEncodingException e ) 171 { 172 throw new RuntimeException ( e.getMessage() ); 173 } 174 str = new HSSFRichTextString( s ); 175 } 176 177 public HSSFRichTextString getStr() 178 { 179 return str; 180 } 181 182 public void setStr( HSSFRichTextString str ) 183 { 184 this.str = str; 185 } 186 187 public String toString() 188 { 189 StringBuffer buffer = new StringBuffer (); 190 191 buffer.append( "[TXO]\n" ); 192 buffer.append( " .options = " ) 193 .append( "0x" ).append( HexDump.toHex( getOptions() ) ) 194 .append( " (" ).append( getOptions() ).append( " )" ); 195 buffer.append( System.getProperty( "line.separator" ) ); 196 buffer.append( " .reserved1 = " ).append( isReserved1() ).append( '\n' ); 197 buffer.append( " .HorizontalTextAlignment = " ).append( getHorizontalTextAlignment() ).append( '\n' ); 198 buffer.append( " .VerticalTextAlignment = " ).append( getVerticalTextAlignment() ).append( '\n' ); 199 buffer.append( " .reserved2 = " ).append( getReserved2() ).append( '\n' ); 200 buffer.append( " .textLocked = " ).append( isTextLocked() ).append( '\n' ); 201 buffer.append( " .reserved3 = " ).append( getReserved3() ).append( '\n' ); 202 buffer.append( " .textOrientation = " ) 203 .append( "0x" ).append( HexDump.toHex( getTextOrientation() ) ) 204 .append( " (" ).append( getTextOrientation() ).append( " )" ); 205 buffer.append( System.getProperty( "line.separator" ) ); 206 buffer.append( " .reserved4 = " ) 207 .append( "0x" ).append( HexDump.toHex( getReserved4() ) ) 208 .append( " (" ).append( getReserved4() ).append( " )" ); 209 buffer.append( System.getProperty( "line.separator" ) ); 210 buffer.append( " .reserved5 = " ) 211 .append( "0x" ).append( HexDump.toHex( getReserved5() ) ) 212 .append( " (" ).append( getReserved5() ).append( " )" ); 213 buffer.append( System.getProperty( "line.separator" ) ); 214 buffer.append( " .reserved6 = " ) 215 .append( "0x" ).append( HexDump.toHex( getReserved6() ) ) 216 .append( " (" ).append( getReserved6() ).append( " )" ); 217 buffer.append( System.getProperty( "line.separator" ) ); 218 buffer.append( " .textLength = " ) 219 .append( "0x" ).append( HexDump.toHex( getTextLength() ) ) 220 .append( " (" ).append( getTextLength() ).append( " )" ); 221 buffer.append( System.getProperty( "line.separator" ) ); 222 buffer.append( " .reserved7 = " ) 223 .append( "0x" ).append( HexDump.toHex( getReserved7() ) ) 224 .append( " (" ).append( getReserved7() ).append( " )" ); 225 buffer.append( System.getProperty( "line.separator" ) ); 226 227 buffer.append( " .string = " ).append(str).append('\n'); 228 229 buffer.append( "[/TXO]\n" ); 230 return buffer.toString(); 231 } 232 } 233 | Popular Tags |