1 /************************************************************************/
2 /* */
3 /* Read/Write document properties to/from RTF. */
4 /* */
5 /************************************************************************/
6
7 # include "docRtfConfig.h"
8
9 # include <stdio.h>
10 # include <ctype.h>
11 # include <stdlib.h>
12
13 # include <appDebugon.h>
14
15 # include <appUnit.h>
16 # include <textOfficeCharset.h>
17 # include <textConverter.h>
18 # include "docRtfReaderImpl.h"
19 # include "docRtfTagEnum.h"
20
21 /************************************************************************/
22 /* */
23 /* Remember Document Properties. */
24 /* */
25 /************************************************************************/
26
27 /************************************************************************/
28 /* */
29 /* Remember the code page for the document. */
30 /* = All values from the Word 2003 spec explicitly included. */
31 /* = String values checked against GNU iconv 'iconv (GNU libc) 2.3.6' */
32 /* = Check strings against iconv -l */
33 /* */
34 /************************************************************************/
35
docRtfSetAnsicpg(struct TextConverter * tc,int ansicpg)36 static int docRtfSetAnsicpg( struct TextConverter * tc,
37 int ansicpg )
38 {
39 char scratch[20];
40
41 switch( ansicpg )
42 {
43 case 437: case 819: case 850: case 852:
44 case 460: case 862: case 863: case 864:
45 case 465: case 866: case 874: case 932:
46 case 936: case 949: case 950:
47 case 1361:
48 sprintf( scratch, "CP%d", ansicpg );
49 textConverterSetNativeEncodingName( tc, scratch );
50 return 0;
51
52 case 708:
53 textConverterSetNativeEncodingName( tc, "ASMO-708" );
54 return 0;
55 case 709:
56 textConverterSetNativeEncodingName( tc, "ASMO_449" );
57 return 0;
58
59 case 1250: case 1251: case 1252: case 1253:
60 case 1254: case 1255: case 1256: case 1257:
61 case 1258:
62 /* sprintf( scratch, "WINDOWS-%d", ansicpg ); */ /* GNU? */
63 sprintf( scratch, "CP%d", ansicpg );
64 textConverterSetNativeEncodingName( tc, scratch );
65 return 0;
66
67 case 10000:
68 textConverterSetNativeEncodingName( tc, "MACINTOSH" );
69 return 0;
70
71 case 710:
72 case 711:
73 case 720:
74 default:
75 LDEB(ansicpg);
76 textConverterSetNativeEncodingName( tc, DOC_RTF_AnsiCharsetName );
77 return -1;
78 }
79 }
80
81 /************************************************************************/
82 /* */
83 /* Remember the document charset. It is translated to a code page */
84 /* where possible. */
85 /* */
86 /************************************************************************/
87
docRtfReadSetDocumentCharset(RtfReader * rrc,int arg)88 static int docRtfReadSetDocumentCharset(
89 RtfReader * rrc,
90 int arg )
91 {
92 struct TextConverter * tc= rrc->rrRtfTextConverter;
93
94 switch( arg )
95 {
96 case DOCcharsetANSI:
97 if ( docRtfSetAnsicpg( tc, 1252 ) )
98 { LDEB(arg); return -1; }
99 return 0;
100
101 case DOCcharsetPC:
102 if ( docRtfSetAnsicpg( tc, 437 ) )
103 { LDEB(arg); return -1; }
104 return 0;
105
106 case DOCcharsetPCA:
107 if ( docRtfSetAnsicpg( tc, 850 ) )
108 { LDEB(arg); return -1; }
109 return 0;
110
111 case DOCcharsetMAC:
112 if ( docRtfSetAnsicpg( tc, 10000 ) )
113 { LDEB(arg); return -1; }
114 return 0;
115
116 default:
117 LDEB(arg); return -1;
118 }
119 }
120
docRtfRememberDocProperty(const RtfControlWord * rcw,int arg,RtfReader * rrc)121 int docRtfRememberDocProperty( const RtfControlWord * rcw,
122 int arg,
123 RtfReader * rrc )
124 {
125 SectionProperties * sp= &(rrc->rrcSectionProperties);
126
127 int charset= -1;
128
129 switch( rcw->rcwID )
130 {
131 case DGpropLEFT_MARGIN:
132 sp->spDocumentGeometry.dgLeftMarginTwips= arg;
133 rrc->rrcGotDocGeometry= 1;
134 break;
135 case DGpropTOP_MARGIN:
136 sp->spDocumentGeometry.dgTopMarginTwips= arg;
137 rrc->rrcGotDocGeometry= 1;
138 break;
139 case DGpropRIGHT_MARGIN:
140 sp->spDocumentGeometry.dgRightMarginTwips= arg;
141 rrc->rrcGotDocGeometry= 1;
142 break;
143 case DGpropBOTTOM_MARGIN:
144 sp->spDocumentGeometry.dgBottomMarginTwips= arg;
145 break;
146 case DGpropPAGE_WIDTH:
147 sp->spDocumentGeometry.dgPageWideTwips= arg;
148 rrc->rrcGotDocGeometry= 1;
149 break;
150 case DGpropPAGE_HEIGHT:
151 sp->spDocumentGeometry.dgPageHighTwips= arg;
152 rrc->rrcGotDocGeometry= 1;
153 break;
154 case DGpropGUTTER:
155 sp->spDocumentGeometry.dgGutterTwips= arg;
156 rrc->rrcGotDocGeometry= 1;
157 break;
158 case DGpropMARGMIR:
159 arg= arg != 0;
160 sp->spDocumentGeometry.dgMirrorMargins= arg;
161 rrc->rrcGotDocGeometry= 1;
162 break;
163
164 case DPpropFACING_PAGES:
165 arg= arg != 0;
166 break;
167 case DPpropGUTTER_HORIZONTAL:
168 arg= arg != 0;
169 break;
170 case DPpropWIDOWCTRL:
171 arg= arg != 0;
172 break;
173 case DPpropTWO_ON_ONE:
174 arg= arg != 0;
175 break;
176 case DPpropDOCTEMP:
177 arg= arg != 0;
178 break;
179
180 case DPpropDEFF:
181 rrc->rrcDefaultFont= arg;
182 if ( docRtfReadMapFont( rrc, &arg, &charset,
183 rrc->rrcDefaultFont ) < 0 )
184 { SLDEB(rcw->rcwWord,arg); }
185 break;
186 case DPpropSTSHFDBCH:
187 rrc->rrcDefaultFontDbch= arg;
188 if ( docRtfReadMapFont( rrc, &arg, &charset,
189 rrc->rrcDefaultFontDbch ) < 0 )
190 { SLDEB(rcw->rcwWord,arg); }
191 break;
192 case DPpropSTSHFLOCH:
193 rrc->rrcDefaultFontLoch= arg;
194 if ( docRtfReadMapFont( rrc, &arg, &charset,
195 rrc->rrcDefaultFontLoch ) < 0 )
196 { SLDEB(rcw->rcwWord,arg); }
197 break;
198 case DPpropSTSHFHICH:
199 rrc->rrcDefaultFontHich= arg;
200 if ( docRtfReadMapFont( rrc, &arg, &charset,
201 rrc->rrcDefaultFontHich ) < 0 )
202 { SLDEB(rcw->rcwWord,arg); }
203 break;
204 case DPpropSTSHFBI:
205 rrc->rrcDefaultFontBi= arg;
206 if ( docRtfReadMapFont( rrc, &arg, &charset,
207 rrc->rrcDefaultFontBi ) < 0 )
208 { SLDEB(rcw->rcwWord,arg); }
209 break;
210
211 case DPpropDOC_CHARSET:
212 if ( docRtfReadSetDocumentCharset( rrc, arg ) )
213 { SLDEB(rcw->rcwWord,arg); return 0; }
214 break;
215 case DPpropANSICPG:
216 if ( docRtfSetAnsicpg( rrc->rrRtfTextConverter, arg ) )
217 { SLDEB(rcw->rcwWord,arg); return 0; }
218 break;
219
220 case DPpropTOP_BORDER:
221 case DPpropBOTTOM_BORDER:
222 case DPpropLEFT_BORDER:
223 case DPpropRIGHT_BORDER:
224 case DPpropHEAD_BORDER:
225 case DPpropFOOT_BORDER:
226 arg= docRtfReadGetBorderNumber( rrc );
227 if ( arg < 0 )
228 { SLDEB(rcw->rcwWord,arg); return -1; }
229 break;
230
231 case DPpropNOTETYPES:
232 docInitFootEndNotesProperties(
233 &(rrc->rrDocument->bdProperties.dpNotesProps) );
234 break;
235
236 case DPprop_IGNORED:
237 return 0;
238
239 default:
240 break;
241 }
242
243 if ( rrc->rrcTraceInProps )
244 {
245 /* Working copy for undo */
246 if ( docSetDocumentProperty( &(rrc->rrcDocumentProperties),
247 rcw->rcwID, arg ) < 0 )
248 { SLDEB(rcw->rcwWord,arg); return 0; }
249
250 PROPmaskADD( &(rrc->rrcDocPropertyMask), rcw->rcwID );
251 }
252 else{
253 /* Document */
254 if ( docSetDocumentProperty( &(rrc->rrDocument->bdProperties),
255 rcw->rcwID, arg ) < 0 )
256 { SLDEB(rcw->rcwWord,arg); return 0; }
257 }
258
259 return 0;
260 }
261
262 /************************************************************************/
263 /* */
264 /* Remember a document property that has a string value. */
265 /* */
266 /************************************************************************/
267
docRtfCommitDocPropText(const RtfControlWord * rcw,RtfReader * rrc)268 int docRtfCommitDocPropText( const RtfControlWord * rcw,
269 RtfReader * rrc )
270 {
271 int rval= 0;
272 const int removeSemicolon= rcw->rcwID == DPpropGENERATOR;
273
274 char * text= (char *)0;
275 int size;
276
277 if ( docRtfStoreSavedText( &text, &size, rrc, removeSemicolon ) )
278 { SDEB(rcw->rcwWord); rval= -1; goto ready; }
279
280 if ( rrc->rrcTraceInProps )
281 {
282 if ( docSetDocumentPropertyString( &(rrc->rrcDocumentProperties),
283 rcw->rcwID, text, size ) )
284 { SDEB(rcw->rcwWord); rval= -1; goto ready; }
285
286 PROPmaskADD( &(rrc->rrcDocPropertyMask), rcw->rcwID );
287 }
288 else{
289 if ( docSetDocumentPropertyString( &(rrc->rrDocument->bdProperties),
290 rcw->rcwID, text, size ) )
291 { SDEB(rcw->rcwWord); rval= -1; goto ready; }
292 }
293
294 ready:
295
296 if ( text )
297 { free( text ); }
298
299 return rval;
300 }
301
302 /************************************************************************/
303 /* */
304 /* A date/time field in the info group. */
305 /* */
306 /************************************************************************/
307
docRtfDocTimeGroup(const RtfControlWord * rcw,int arg,RtfReader * rrc)308 int docRtfDocTimeGroup( const RtfControlWord * rcw,
309 int arg,
310 RtfReader * rrc )
311 {
312 utilInvalidateTime( &(rrc->rrcTm) );
313
314 if ( docRtfReadGroup( rcw, 0, 0, rrc,
315 (RtfControlWord *)0, docRtfRefuseText, (RtfCommitGroup)0 ) )
316 { SLDEB(rcw->rcwWord,arg); return -1; }
317
318 if ( rrc->rrcTraceInProps )
319 {
320 if ( docSetDocumentPropertyTime( &(rrc->rrcDocumentProperties),
321 rcw->rcwID, &(rrc->rrcTm) ) )
322 { SDEB(rcw->rcwWord); return -1; }
323
324 PROPmaskADD( &(rrc->rrcDocPropertyMask), rcw->rcwID );
325 }
326 else{
327 if ( docSetDocumentPropertyTime( &(rrc->rrDocument->bdProperties),
328 rcw->rcwID, &(rrc->rrcTm) ) )
329 { SDEB(rcw->rcwWord); return -1; }
330 }
331
332 return 0;
333 }
334
335 /************************************************************************/
336 /* */
337 /* Remember fields from dates and times. */
338 /* */
339 /************************************************************************/
340
docRtfReadTimeField(const RtfControlWord * rcw,int arg,RtfReader * rrc)341 int docRtfReadTimeField( const RtfControlWord * rcw,
342 int arg,
343 RtfReader * rrc )
344 {
345 switch( rcw->rcwID )
346 {
347 case RTFidHR:
348 rrc->rrcTm.tm_hour= arg;
349 break;
350 case RTFidMIN:
351 rrc->rrcTm.tm_min= arg;
352 break;
353 case RTFidSEC:
354 rrc->rrcTm.tm_sec= arg;
355 break;
356 case RTFidDY:
357 rrc->rrcTm.tm_mday= arg;
358 break;
359 case RTFidMO:
360 rrc->rrcTm.tm_mon= arg- 1;
361 break;
362 case RTFidYR:
363 rrc->rrcTm.tm_year= arg- 1900;
364 break;
365 }
366
367 return 0;
368 }
369
370 /************************************************************************/
371 /* */
372 /* Remember fields from dates and times. */
373 /* */
374 /************************************************************************/
375
docRtfSelectionOpen(const RtfControlWord * rcw,int arg,RtfReader * rrc)376 int docRtfSelectionOpen( const RtfControlWord * rcw,
377 int arg,
378 RtfReader * rrc )
379 {
380 DocumentProperties * dp= &(rrc->rrDocument->bdProperties);
381
382 dp->dpHasOpenEnd= 1;
383
384 if ( docRtfReadGroup( rcw, 0, 0, rrc, (RtfControlWord *)0,
385 (RtfAddTextParticule)0, (RtfCommitGroup)0 ) )
386 { SLDEB(rcw->rcwWord,arg); return -1; }
387
388 return 0;
389 }
390