filters

wp6.cpp
1/* This file is part of the KDE project
2 Copyright (C) 2002 Ariya Hidayat <ariya@kde.org>
3
4 This library is free software; you can redistribute it and/or
5 modify it under the terms of the GNU Library General Public
6 License as published by the Free Software Foundation; either
7 version 2 of the License, or (at your option) any later version.
8
9 This library is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 Library General Public License for more details.
13
14 You should have received a copy of the GNU Library General Public License
15 along with this library; see the file COPYING.LIB. If not, write to
16 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
17 * Boston, MA 02110-1301, USA.
18*/
19
20#include <config.h>
21
22#ifdef HAVE_UNISTD_H
23#include <unistd.h>
24#endif
25
26#include <tqtextcodec.h>
27#include <tqfile.h>
28#include <tqfileinfo.h>
29#include <tqtextstream.h>
30#include <tqvaluevector.h>
31
32#include <KWEFBaseWorker.h>
33#include <KWEFKWordLeader.h>
34#include <KWEFUtil.h>
35
36#include <wp6.h>
37
38bool WPSixWorker::doOpenFile(const TQString& filenameOut, const TQString& /*to*/)
39{
40 filename = filenameOut;
41 outfile.setName( filename );
42 if( !outfile.open( IO_WriteOnly ) )
43 return false;
44
45 output.setDevice( &outfile );
46 output.setByteOrder (TQDataStream::LittleEndian);
47 return true;
48}
49
50bool WPSixWorker::doCloseFile(void)
51{
52 // asssume we're at the end of the file
53 TQ_UINT32 total_filesize = outfile.at();
54
55 // close the file first
56 outfile.close();
57
58 // reopen for read and write
59 if( !outfile.open( IO_ReadWrite ) )
60 return false;
61 output.setDevice( &outfile );
62
63 // now it's time to fix-up some header fields
64
65 // fix for offset 12, int32, filesize
66 outfile.at( 20 );
67 output << total_filesize;
68
69 // offset 4, int32, pointer to document area
70 outfile.at( 4 );
71 output << document_area_ptr;
72
73 outfile.close();
74 return true;
75}
76
77bool WPSixWorker::doOpenDocument(void)
78{
79 // write WP document header
80 // note that some fields are still "dummy"
81
82 // magic id: -1, "WPC"
83 TQ_UINT8 magic[] = { 0xff, 0x57, 0x50, 0x43 };
84 for( int i=0; i<4; i++ ) output << magic[i];
85
86 // pointer to document area (dummy, will be fixed later)
87 TQ_UINT8 docptr[] = { 0x0E, 0x02, 0x00, 0x00 } ;
88 for( int i=0; i<4; i++ ) output << docptr[i];
89
90 // write product type ( 1 = WordPerfect )
91 TQ_UINT8 product_type = 1;
92 output << product_type;
93
94 // write file type ( 10 = WordPerfect document )
95 TQ_UINT8 file_type = 10;
96 output << file_type;
97
98 // write version (TODO explain)
99 TQ_UINT16 version = 0x0202;
100 output << version;
101
102 // write encryption flag ( 0 = not encrypted )
103 TQ_UINT16 encrypt = 0;
104 output << encrypt;
105
106 // offset to index header (always 0x200?)
107 TQ_UINT16 index_header_ptr = 0x200;
108 output << index_header_ptr;
109
110 // beginning of extended file header (always 5)
111 TQ_UINT32 extheader = 5;
112 output << extheader;
113
114 // filesize (dummy, will be fixed later)
115 TQ_UINT32 filesize = 0;
116 output << filesize;
117
118 // filler 488 bytes
119 TQ_UINT8 dummy = 0;
120 for( int i=0; i<488; i++ ) output << dummy;
121
122 // index header (specified 0 index!)
123 TQ_UINT8 index_header[] = { 2, 0, 0, 0, 0, 0, 0, 0, 0, 0,
124 0, 0, 0, 0 };
125 for( int i=0; i<14; i++ ) output << index_header[i];
126
127 // document area starts, mark it for the header fields
128 document_area_ptr = output.device()->at();
129
130 return true;
131}
132
133bool WPSixWorker::doCloseDocument(void)
134{
135 return true;
136}
137
138// this helper functions "escape" plain Unicode string to WP-compliance string
139// what it does: converting spaces and tabs to hard-spaces and hard-tabs
140// TODO handle Unicode characters using WP charsets
141static TQCString WPSixEscape( const TQString& text )
142{
143 TQCString result;
144
145 for( unsigned int i=0; i < text.length(); i++ )
146 {
147 int c = text[i].unicode();
148 if( c < 32 ) result += '.';
149 else if ( c == 32 ) result += 0x80 ; // hard space
150 else if ( c < 128 ) result += text[i].latin1();
151 else result += '.';
152 }
153
154 return result;
155}
156
157bool WPSixWorker::doFullParagraph(const TQString& paraText,
158 const LayoutData& layout, const ValueListFormatData& paraFormatDataList)
159{
160 // handle paragraph alignment/justification (default to left)
161 unsigned char wp_align[] = { 0xd3, 5, 12, 0, 0, 1, 0, 0, 2, 12, 0, 0xd3 };
162 if( layout.alignment == "left" ) wp_align[7] = 0;
163 if( layout.alignment == "justify" ) wp_align[7] = 1;
164 if( layout.alignment == "center" ) wp_align[7] = 2;
165 if( layout.alignment == "right" ) wp_align[7] = 3;
166 output.writeRawBytes( (const char*)wp_align, 12 );
167
168 ValueListFormatData::ConstIterator it;
169 for( it = paraFormatDataList.begin(); it!=paraFormatDataList.end(); ++it )
170 {
171 const FormatData& formatData = *it;
172
173 // only if the format is for text (id==1)
174 if( formatData.id == 1 )
175 {
176
177 TQ_UINT8 attr = 0; //invalid
178 if( formatData.text.weight >= 75 ) attr = 12; // bold
179 if( formatData.text.italic ) attr = 8;
180 if( formatData.text.underline )
181 {
182 if( formatData.text.underlineValue == "double" )
183 attr = 11; // double underline
184 else
185 attr = 14; // single underline
186 }
187 if( formatData.text.verticalAlignment == 1 ) attr = 6; //subscript
188 if( formatData.text.verticalAlignment == 2 ) attr = 5; //superscript
189 if( formatData.text.strikeout ) attr = 13;
190
191 TQColor fgColor = formatData.text.fgColor;
192 TQColor bgColor = formatData.text.bgColor;
193
194 // due to the file format, before writing the text we must
195 // write some refix-code (such as Bold On) and possibly appropriate suffix-code (Bold Off)
196
197 // attribute on
198 if( attr > 0 ) output << (TQ_UINT8)0xf2 << attr << (TQ_UINT8)0xf2;
199
200 // set font color
201 if( fgColor.isValid() )
202 {
203 TQ_UINT8 wp_color[] = { 0xd4, 0x18, 16, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0xd4 };
204 wp_color[7] = (TQ_UINT8) fgColor.red();
205 wp_color[8] = (TQ_UINT8) fgColor.green();
206 wp_color[9] = (TQ_UINT8) fgColor.blue();
207 output.writeRawBytes( (const char*)wp_color, 16 );
208 }
209
210 // highlight on (background color)
211 if( bgColor.isValid() )
212 {
213 output << (TQ_UINT8) 0xfb;
214 output << (TQ_UINT8)bgColor.red() << (TQ_UINT8)bgColor.green() << (TQ_UINT8)bgColor.blue();
215 output << (TQ_UINT8) 100 << (TQ_UINT8) 0xfb;
216 }
217
218 // the text itself, "escape" it first
219 TQCString out = WPSixEscape( paraText.mid( formatData.pos, formatData.len ) );
220 output.writeRawBytes( (const char*)out, out.length() );
221
222 // attribute off
223 if( attr > 0 ) output << (TQ_UINT8)0xf3 << attr << (TQ_UINT8)0xf3;
224
225 // highlight off
226 if( bgColor.isValid() )
227 {
228 output << (TQ_UINT8) 0xfc;
229 output << (TQ_UINT8)bgColor.red() << (TQ_UINT8)bgColor.green() << (TQ_UINT8)bgColor.blue();
230 output << (TQ_UINT8) 100 << (TQ_UINT8) 0xfc;
231 }
232 }
233
234 }
235
236 // write hard-return
237 output << (TQ_UINT8) 0xcc;
238
239 return true;
240}
241
Paragraph layout.
TQString alignment
left, right, center, justify
bool underline
Any underline? (If true, we do not know if simple or double or what else).
bool strikeout
true if strikeout
TQString underlineValue
"value" of the underline: single, double, bold-single...