1 package org.apache.maven.doxia.module.rtf;
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 import java.io.BufferedOutputStream;
23 import java.io.FileOutputStream;
24 import java.io.IOException;
25 import java.io.OutputStream;
26 import java.io.Writer;
27 import java.util.Vector;
28
29
30
31
32
33
34 class WMFWriter
35 {
36
37
38
39
40
41 private static Record trailer = new Record( 0, null );
42
43
44
45
46 private short fileType;
47
48 private short headerSize;
49
50 private short version;
51
52 private int fileSize;
53
54 private short numOfObjects;
55
56 private int maxRecordSize;
57
58 private short numOfParams;
59
60 private Vector records;
61
62 WMFWriter()
63 {
64 fileType = 2;
65 headerSize = 9;
66 version = 0x0300;
67 fileSize = headerSize + trailer.size();
68 numOfObjects = 0;
69 maxRecordSize = trailer.size();
70 numOfParams = 0;
71
72 records = new Vector();
73 }
74
75 void add( Record record )
76 {
77 records.addElement( record );
78
79 int size = record.size();
80 fileSize += size;
81 if ( size > maxRecordSize )
82 {
83 maxRecordSize = size;
84 }
85 }
86
87 int size()
88 {
89 return fileSize;
90 }
91
92 void write( String fileName )
93 throws IOException
94 {
95 BufferedOutputStream out = new BufferedOutputStream( new FileOutputStream( fileName ) );
96 write( out );
97 out.flush();
98 out.close();
99 }
100
101 void write( OutputStream out )
102 throws IOException
103 {
104 write16( fileType, out );
105 write16( headerSize, out );
106 write16( version, out );
107 write32( fileSize, out );
108 write16( numOfObjects, out );
109 write32( maxRecordSize, out );
110 write16( numOfParams, out );
111
112 for ( int i = 0, n = records.size(); i < n; ++i )
113 {
114 Record record = (Record) records.elementAt( i );
115 record.write( out );
116 }
117
118 trailer.write( out );
119 }
120
121
122
123
124 static void write16( int word, OutputStream out )
125 throws IOException
126 {
127 out.write( word );
128 out.write( word >> 8 );
129 }
130
131
132
133
134 static void write32( int dword, OutputStream out )
135 throws IOException
136 {
137 out.write( dword );
138 out.write( dword >> 8 );
139 out.write( dword >> 16 );
140 out.write( dword >> 24 );
141 }
142
143 void print( Writer out )
144 throws IOException
145 {
146 print16( fileType, out );
147 print16( headerSize, out );
148 print16( version, out );
149 print32( fileSize, out );
150 print16( numOfObjects, out );
151 print32( maxRecordSize, out );
152 print16( numOfParams, out );
153 out.write( System.getProperty( "line.separator" ) );
154
155 for ( int i = 0, n = records.size(); i < n; ++i )
156 {
157 Record record = (Record) records.elementAt( i );
158 record.print( out );
159 }
160
161 trailer.print( out );
162 }
163
164 static void print16( int word, Writer out )
165 throws IOException
166 {
167 byte[] buf = new byte[2];
168 buf[0] = (byte) word;
169 buf[1] = (byte) ( word >> 8 );
170 print( buf, 0, 2, out );
171 }
172
173 static void print32( int dword, Writer out )
174 throws IOException
175 {
176 byte[] buf = new byte[4];
177 buf[0] = (byte) dword;
178 buf[1] = (byte) ( dword >> 8 );
179 buf[2] = (byte) ( dword >> 16 );
180 buf[3] = (byte) ( dword >> 24 );
181 print( buf, 0, 4, out );
182 }
183
184 static void print( byte[] buf, int off, int len, Writer out )
185 throws IOException
186 {
187 char[] cbuf = new char[2 * len];
188
189 for ( int i = off, j = 0, n = off + len; i < n; ++i )
190 {
191 int d = ( buf[i] >> 4 ) & 0x0f;
192 if ( d < 10 )
193 {
194 cbuf[j++] = (char) ( '0' + d );
195 }
196 else
197 {
198 cbuf[j++] = (char) ( 'a' + ( d - 10 ) );
199 }
200 d = buf[i] & 0x0f;
201 if ( d < 10 )
202 {
203 cbuf[j++] = (char) ( '0' + d );
204 }
205 else
206 {
207 cbuf[j++] = (char) ( 'a' + ( d - 10 ) );
208 }
209 }
210
211 out.write( cbuf );
212 }
213
214 static void print( byte[] buf, int off, int len, Writer out, int lw )
215 throws IOException
216 {
217 String ls = System.getProperty( "line.separator" );
218 for ( int i = off; len > 0; )
219 {
220 int n = Math.min( len, lw / 2 );
221 print( buf, i, n, out );
222 out.write( ls );
223 len -= n;
224 i += n;
225 }
226 }
227
228
229
230
231 static class Record
232 {
233 protected int size;
234
235 private short function;
236
237 private short[] parameters;
238
239 Record( int function, int[] parameters )
240 {
241 this.function = (short) function;
242 if ( parameters != null )
243 {
244 this.parameters = new short[parameters.length];
245 for ( int i = 0; i < parameters.length; ++i )
246 {
247 this.parameters[i] = (short) parameters[i];
248 }
249 }
250 size = 3 + ( parameters == null ? 0 : parameters.length );
251 }
252
253 int size()
254 {
255 return size;
256 }
257
258 void write( OutputStream out )
259 throws IOException
260 {
261 write32( size, out );
262 write16( function, out );
263 if ( parameters != null )
264 {
265 for ( int i = 0; i < parameters.length; ++i )
266 {
267 write16( parameters[i], out );
268 }
269 }
270 }
271
272 void print( Writer out )
273 throws IOException
274 {
275 print32( size, out );
276 print16( function, out );
277 if ( parameters != null )
278 {
279 for ( int i = 0; i < parameters.length; ++i )
280 {
281 print16( parameters[i], out );
282 }
283 }
284 }
285
286 }
287
288
289
290
291 static class Dib
292 {
293
294
295
296 static final int BI_RGB = 0;
297
298 static final int BI_RLE8 = 1;
299
300 static final int BI_RLE4 = 2;
301
302 static final int BI_BITFIELDS = 3;
303
304
305
306
307 final int biSize = 40;
308
309 int biWidth;
310
311 int biHeight;
312
313 final short biPlanes = 1;
314
315 short biBitCount;
316
317 int biCompression;
318
319 int biSizeImage;
320
321 int biXPelsPerMeter;
322
323 int biYPelsPerMeter;
324
325 int biClrUsed;
326
327 int biClrImportant;
328
329 byte[] palette;
330
331 byte[] bitmap;
332
333 int size()
334 {
335 int size = biSize;
336 if ( palette != null )
337 {
338 size += palette.length;
339 }
340 if ( bitmap != null )
341 {
342 if ( biSizeImage != 0 )
343 {
344 size += biSizeImage;
345 }
346 else
347 {
348 size += bitmap.length;
349 }
350 }
351 return size / 2;
352 }
353
354 void write( OutputStream out )
355 throws IOException
356 {
357 write32( biSize, out );
358 write32( biWidth, out );
359 write32( biHeight, out );
360 write16( biPlanes, out );
361 write16( biBitCount, out );
362 write32( biCompression, out );
363 write32( biSizeImage, out );
364 write32( biXPelsPerMeter, out );
365 write32( biYPelsPerMeter, out );
366 write32( biClrUsed, out );
367 write32( biClrImportant, out );
368 if ( palette != null )
369 {
370 out.write( palette );
371 }
372 if ( bitmap != null )
373 {
374 if ( biSizeImage != 0 )
375 {
376 out.write( bitmap, 0, biSizeImage );
377 }
378 else
379 {
380 out.write( bitmap );
381 }
382 }
383 }
384
385 void print( Writer out )
386 throws IOException
387 {
388 String ls = System.getProperty( "line.separator" );
389
390 print32( biSize, out );
391 print32( biWidth, out );
392 print32( biHeight, out );
393 print16( biPlanes, out );
394 print16( biBitCount, out );
395 out.write( ls );
396
397 print32( biCompression, out );
398 print32( biSizeImage, out );
399 print32( biXPelsPerMeter, out );
400 print32( biYPelsPerMeter, out );
401 print32( biClrUsed, out );
402 print32( biClrImportant, out );
403 out.write( ls );
404
405 if ( palette != null )
406 {
407 WMFWriter.print( palette, 0, palette.length, out, 64 );
408 }
409
410 if ( bitmap != null )
411 {
412 int len = ( biSizeImage != 0 ) ? biSizeImage : bitmap.length;
413 WMFWriter.print( bitmap, 0, len, out, 76 );
414 }
415 }
416
417 static int rlEncode8( byte[] inBuf, int inOff, int inLen, byte[] outBuf, int outOff )
418 {
419 int i1, i2, j, k, n;
420 int len;
421
422 for ( i1 = inOff, j = outOff, n = ( inOff + inLen ); i1 < n; )
423 {
424 for ( i2 = ( i1 + 1 ), len = 1; i2 < n; ++i2, ++len )
425 {
426 if ( inBuf[i2] != inBuf[i2 - 1] )
427 {
428 break;
429 }
430 }
431
432 if ( len > 1 )
433 {
434 while ( len > 255 )
435 {
436 outBuf[j++] = (byte) 255;
437 outBuf[j++] = inBuf[i1];
438 len -= 255;
439 }
440 if ( len > 0 )
441 {
442 outBuf[j++] = (byte) len;
443 outBuf[j++] = inBuf[i1];
444 }
445 i1 = i2;
446 continue;
447 }
448
449 for ( ++i2; i2 < n; ++i2, ++len )
450 {
451 if ( inBuf[i2] == inBuf[i2 - 1] )
452 {
453 break;
454 }
455 }
456
457 while ( len > 255 )
458 {
459 outBuf[j++] = 0;
460 outBuf[j++] = (byte) 255;
461 for ( k = 0; k < 255; ++k )
462 {
463 outBuf[j++] = inBuf[i1++];
464 }
465 outBuf[j++] = (byte) 0;
466 len -= 255;
467 }
468
469 if ( len > 2 )
470 {
471 outBuf[j++] = 0;
472 outBuf[j++] = (byte) len;
473 for ( k = 0; k < len; ++k )
474 {
475 outBuf[j++] = inBuf[i1++];
476 }
477 if ( len % 2 != 0 )
478 {
479 outBuf[j++] = 0;
480 }
481 }
482 else
483 {
484 while ( len > 0 )
485 {
486 outBuf[j++] = 1;
487 outBuf[j++] = inBuf[i1++];
488 len -= 1;
489 }
490 }
491 }
492
493 return j - outOff;
494 }
495 }
496
497 static class DibBitBltRecord
498 extends Record
499 {
500
501
502
503 static final int P_COUNT = 8;
504
505
506
507
508 static final int P_ROP_L = 0;
509
510 static final int P_ROP_H = 1;
511
512 static final int P_YSRC = 2;
513
514 static final int P_XSRC = 3;
515
516 static final int P_HEIGHT = 4;
517
518 static final int P_WIDTH = 5;
519
520 static final int P_YDST = 6;
521
522 static final int P_XDST = 7;
523
524 private Dib dib;
525
526 DibBitBltRecord( int[] parameters, Dib dib )
527 {
528 super( 0x0940, parameters );
529 size += dib.size();
530 this.dib = dib;
531 }
532
533
534 void write( OutputStream out )
535 throws IOException
536 {
537 super.write( out );
538 dib.write( out );
539 }
540
541
542 void print( Writer out )
543 throws IOException
544 {
545 super.print( out );
546 dib.print( out );
547 }
548 }
549 }