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 
12 #   include	<appDebugon.h>
13 
14 #   include	<textOfficeCharset.h>
15 #   include	"docRtfWriterImpl.h"
16 #   include	"docRtfTags.h"
17 
18 /************************************************************************/
19 /*									*/
20 /*  Save Document Properties to RTF.					*/
21 /*									*/
22 /************************************************************************/
23 
docRtfSaveInfo(RtfWriter * rw,const char * tag,const MemoryBuffer * info)24 static int docRtfSaveInfo(	RtfWriter *		rw,
25 				const char *		tag,
26 				const MemoryBuffer *	info )
27     {
28     const int		addSemicolon= 0;
29 
30     docRtfWriteDocEncodedStringDestination( rw, tag,
31 				    (const char *)info->mbBytes,
32 				    info->mbSize, addSemicolon );
33 
34     docRtfWriteNextLine( rw );
35 
36     return 0;
37     }
38 
docRtfSaveDate(RtfWriter * rw,const char * tag,const struct tm * tm)39 int docRtfSaveDate(	RtfWriter *		rw,
40 			const char *		tag,
41 			const struct tm *	tm )
42     {
43     docRtfWriteDestinationBegin( rw, tag );
44 
45     if  ( tm->tm_mday != 0 )
46 	{
47 	docRtfWriteArgTag( rw, "yr",	tm->tm_year+ 1900 );
48 	docRtfWriteArgTag( rw, "mo",	tm->tm_mon+ 1 );
49 	docRtfWriteArgTag( rw, "dy",	tm->tm_mday );
50 	docRtfWriteArgTag( rw, "hr",	tm->tm_hour );
51 	docRtfWriteArgTag( rw, "min",	tm->tm_min );
52 	docRtfWriteArgTag( rw, "sec",	tm->tm_sec );
53 	}
54 
55     docRtfWriteDestinationEnd( rw );
56     docRtfWriteNextLine( rw );
57 
58     return 0;
59     }
60 
docRtfSaveDocumentProperties(RtfWriter * rw,int fet,const PropertyMask * dpMask,const DocumentProperties * dp)61 int docRtfSaveDocumentProperties(	RtfWriter *			rw,
62 					int				fet,
63 					const PropertyMask *		dpMask,
64 					const DocumentProperties *	dp )
65     {
66     const int			anyway= 1;
67     const DocumentGeometry *	dg= &(dp->dpGeometry);
68 
69     /* NO! We always write ansi 1252 documents
70     int				ansicpg= dp->dpAnsiCodepage;
71 
72     if  ( ansicpg >= 0 )
73 	{
74 	if  ( docRtfSetAnsicpg( rw->rwRtfTextConverter, ansicpg ) )
75 	    { LDEB(ansicpg);	}
76 	}
77     */
78 
79     if  ( PROPmaskISSET( dpMask, DPpropDEFF ) )
80 	{
81 	int	deff= docRtfWriteGetDefaultFont( rw, dp->dpDefaultFont );
82 
83 	if  ( deff >= 0 )
84 	    { docRtfWriteArgTag( rw, "deff", deff );	}
85 	}
86 
87     if  ( PROPmaskISSET( dpMask, DPpropDEFLANG ) )
88 	{ docRtfWriteArgTag( rw, "deflang", dp->dpDefaultLanguage );	}
89 
90     if  ( PROPmaskISSET( dpMask, DPpropRTOL ) )
91 	{
92 	docRtfWriteAltTag( rw, "rtldoc", "ltrdoc", dp->dpRToL );
93 	}
94 
95     /* Strictly spoken, this is not a document property */
96     docRtfWriteArgTag( rw, "uc", 1 );
97 
98     if  ( PROPmaskISSET( dpMask, DPpropFONTTABLE ) )
99 	{
100 	docRtfWriteNextLine( rw );
101 	docRtfWriteFontTable( rw );
102 	}
103 
104     if  ( PROPmaskISSET( dpMask, DPpropCOLORTABLE ) )
105 	{
106 	docRtfWriteNextLine( rw );
107 	docRtfWriteColorTable( rw, dp );
108 	}
109 
110     if  ( PROPmaskISSET( dpMask, DPpropSTYLESHEET ) )
111 	{
112 	docRtfWriteNextLine( rw );
113 	docRtfWriteStyleSheet( rw, &(rw->rwDocument->bdStyleSheet) );
114 	}
115 
116     if  ( PROPmaskISSET( dpMask, DPpropLISTTABLE ) )
117 	{
118 	docRtfWriteNextLine( rw );
119 	docRtfWriteListTable( rw, &(dp->dpListAdmin->laListTable) );
120 	}
121 
122     if  ( PROPmaskISSET( dpMask, DPpropLISTOVERRIDETABLE ) )
123 	{
124 	docRtfWriteNextLine( rw );
125 	docRtfWriteListOverrideTable( rw,
126 				    &(dp->dpListAdmin->laListOverrideTable) );
127 	}
128 
129     if  ( PROPmaskISSET( dpMask, DPpropGENERATOR ) )
130 	{ docRtfSaveInfo( rw, RTFtag__generator, &(dp->dpGeneratorWrite) ); }
131 
132     if  ( PROPmaskISSET( dpMask, DPpropTITLE )		||
133 	  PROPmaskISSET( dpMask, DPpropAUTHOR )		||
134 	  PROPmaskISSET( dpMask, DPpropCOMPANY )	||
135 	  PROPmaskISSET( dpMask, DPpropSUBJECT )	||
136 	  PROPmaskISSET( dpMask, DPpropKEYWORDS )	||
137 	  PROPmaskISSET( dpMask, DPpropDOCCOMM )	||
138 	  PROPmaskISSET( dpMask, DPpropHLINKBASE )	||
139 	  PROPmaskISSET( dpMask, DPpropCREATIM )	||
140 	  PROPmaskISSET( dpMask, DPpropREVTIM )		||
141 	  PROPmaskISSET( dpMask, DPpropPRINTIM )	)
142 	{
143 	docRtfWriteNextLine( rw );
144 	docRtfWriteDestinationBegin( rw, "info" );
145 	docRtfWriteNextLine( rw );
146 
147 	if  ( PROPmaskISSET( dpMask, DPpropTITLE ) )
148 	    { docRtfSaveInfo( rw, "title",	&(dp->dpTitle) );	}
149 	if  ( PROPmaskISSET( dpMask, DPpropAUTHOR ) )
150 	    { docRtfSaveInfo( rw, "author",	&(dp->dpAuthor) );	}
151 	if  ( PROPmaskISSET( dpMask, DPpropCOMPANY ) )
152 	    { docRtfSaveInfo( rw, "company",	&(dp->dpCompany) );	}
153 	if  ( PROPmaskISSET( dpMask, DPpropSUBJECT ) )
154 	    { docRtfSaveInfo( rw, "subject",	&(dp->dpSubject) );	}
155 	if  ( PROPmaskISSET( dpMask, DPpropKEYWORDS ) )
156 	    { docRtfSaveInfo( rw, "keywords",	&(dp->dpKeywords) );	}
157 	if  ( PROPmaskISSET( dpMask, DPpropDOCCOMM ) )
158 	    { docRtfSaveInfo( rw, "doccomm",	&(dp->dpDoccomm) );	}
159 	if  ( PROPmaskISSET( dpMask, DPpropHLINKBASE ) )
160 	    { docRtfSaveInfo( rw, RTFtag_hlinkbase, &(dp->dpHlinkbase) );	}
161 
162 	if  ( PROPmaskISSET( dpMask, DPpropCREATIM ) )
163 	    { docRtfSaveDate( rw, "creatim",	&(dp->dpCreatim) );	}
164 	if  ( PROPmaskISSET( dpMask, DPpropREVTIM ) )
165 	    { docRtfSaveDate( rw, RTFtag_revtim, &(dp->dpRevtim) );	}
166 	if  ( PROPmaskISSET( dpMask, DPpropPRINTIM ) )
167 	    { docRtfSaveDate( rw, "printim",	&(dp->dpPrintim) );	}
168 
169 	docRtfWriteDestinationEnd( rw );
170 	}
171 
172     docRtfWriteNextLine( rw );
173 
174     if  ( PROPmaskISSET( dpMask, DGpropPAGE_WIDTH ) )
175     	{ docRtfWriteArgTag( rw, "paperw", dg->dgPageWideTwips );	}
176     if  ( PROPmaskISSET( dpMask, DGpropPAGE_HEIGHT ) )
177     	{ docRtfWriteArgTag( rw, "paperh", dg->dgPageHighTwips );	}
178 
179     if  ( PROPmaskISSET( dpMask, DGpropLEFT_MARGIN ) )
180     	{ docRtfWriteArgTag( rw, "margl", dg->dgLeftMarginTwips );	}
181     if  ( PROPmaskISSET( dpMask, DGpropRIGHT_MARGIN ) )
182     	{ docRtfWriteArgTag( rw, "margr", dg->dgRightMarginTwips );	}
183     if  ( PROPmaskISSET( dpMask, DGpropTOP_MARGIN ) )
184     	{ docRtfWriteArgTag( rw, "margt", dg->dgTopMarginTwips );	}
185     if  ( PROPmaskISSET( dpMask, DGpropBOTTOM_MARGIN ) )
186     	{ docRtfWriteArgTag( rw, "margb", dg->dgBottomMarginTwips );	}
187 
188     if  ( PROPmaskISSET( dpMask, DGpropGUTTER ) )
189 	{ docRtfWriteArgTag( rw, "gutter", dg->dgGutterTwips ); }
190     if  ( PROPmaskISSET( dpMask, DGpropMARGMIR ) )
191 	{ docRtfWriteTag( rw, "margmirror" ); }
192 
193     if  ( PROPmaskISSET( dpMask, DPpropFACING_PAGES ) )
194 	{ docRtfWriteFlagTag( rw, "facingp", dp->dpHasFacingPages );	}
195     if  ( PROPmaskISSET( dpMask, DPpropGUTTER_HORIZONTAL ) )
196 	{ docRtfWriteFlagTag( rw, "gutterprl", dp->dpGutterHorizontal ); }
197 
198     if  ( PROPmaskISSET( dpMask, DPpropWIDOWCTRL ) )
199 	{ docRtfWriteFlagTag( rw, "widowctrl", dp->dpWidowControl );	}
200 
201     if  ( PROPmaskISSET( dpMask, DPpropTWO_ON_ONE ) )
202 	{ docRtfWriteFlagTag( rw, "twoonone", dp->dpTwoOnOne );	}
203     if  ( PROPmaskISSET( dpMask, DPpropDOCTEMP ) )
204 	{ docRtfWriteFlagTag( rw, "doctemp", dp->dpIsDocumentTemplate ); }
205 
206     if  ( dp->dpTabIntervalTwips > 0 && dp->dpTabIntervalTwips != 720 )
207 	{ docRtfWriteArgTag( rw, "deftab", dp->dpTabIntervalTwips ); }
208 
209     docRtfWriteNextLine( rw );
210 
211     if  ( fet >= 0 )
212 	{ docRtfWriteArgTag( rw, RTFtag_fet, fet );	}
213 
214     docRtfSaveNotesProperties( rw, dpMask,
215 			    &(dp->dpNotesProps.fepFootnotesProps),
216 			    DOCdocFOOTNOTE_PROP_MAP, "ftnstart",
217 			    DOCrtf_DocFootNotesJustificationTags,
218 			    DOCrtf_DocFootNotesJustificationTagCount,
219 			    DOCrtf_DocFootNotesPlacementTags,
220 			    DOCrtf_DocFootNotesPlacementTagCount,
221 			    DOCrtf_DocFootNotesRestartTags,
222 			    DOCrtf_DocFootNotesRestartTagCount,
223 			    DOCrtf_DocFootNotesNumberStyleTags,
224 			    DOCrtf_DocFootNotesNumberStyleTagCount );
225 
226     docRtfSaveNotesProperties( rw, dpMask,
227 			    &(dp->dpNotesProps.fepEndnotesProps),
228 			    DOCdocENDNOTE_PROP_MAP, "aftnstart",
229 			    DOCrtf_DocEndNotesJustificationTags,
230 			    DOCrtf_DocEndNotesJustificationTagCount,
231 			    DOCrtf_DocEndNotesPlacementTags,
232 			    DOCrtf_DocEndNotesPlacementTagCount,
233 			    DOCrtf_DocEndNotesRestartTags,
234 			    DOCrtf_DocEndNotesRestartTagCount,
235 			    DOCrtf_DocEndNotesNumberStyleTags,
236 			    DOCrtf_DocEndNotesNumberStyleTagCount );
237 
238     if  ( PROPmaskISSET( dpMask, DPpropTOP_BORDER ) )
239 	{
240 	docRtfSaveBorderByNumber( rw, "pgbrdrt",
241 					dp->dpTopBorderNumber, anyway );
242 	}
243     if  ( PROPmaskISSET( dpMask, DPpropBOTTOM_BORDER ) )
244 	{
245 	docRtfSaveBorderByNumber( rw, "pgbrdrb",
246 					dp->dpBottomBorderNumber, anyway );
247 	}
248     if  ( PROPmaskISSET( dpMask, DPpropLEFT_BORDER ) )
249 	{
250 	docRtfSaveBorderByNumber( rw, "pgbrdrl",
251 					dp->dpLeftBorderNumber, anyway );
252 	}
253     if  ( PROPmaskISSET( dpMask, DPpropRIGHT_BORDER ) )
254 	{
255 	docRtfSaveBorderByNumber( rw, "pgbrdrr",
256 					dp->dpRightBorderNumber, anyway );
257 	}
258     if  ( PROPmaskISSET( dpMask, DPpropHEAD_BORDER ) )
259 	{
260 	docRtfSaveBorderByNumber( rw, "pgbrdrhead",
261 					dp->dpHeadBorderNumber, anyway );
262 	}
263     if  ( PROPmaskISSET( dpMask, DPpropFOOT_BORDER ) )
264 	{
265 	docRtfSaveBorderByNumber( rw, "pgbrdrfoot",
266 					dp->dpFootBorderNumber, anyway );
267 	}
268 
269     docRtfWriteNextLine( rw );
270 
271     return 0;
272     }
273 
274 /************************************************************************/
275 /*									*/
276 /*  Save the various separators relating to notes.			*/
277 /*									*/
278 /************************************************************************/
279 
docRtfSaveDocNotesSeparators(RtfWriter * rw,const BufferDocument * bd)280 int docRtfSaveDocNotesSeparators(	RtfWriter *		rw,
281 					const BufferDocument *	bd )
282     {
283     const int			evenIfAbsent= 0;
284     const int			forcePar= 0;
285 
286     if  ( docRtfSaveDocumentTree( rw, "ftnsep", &(bd->bdEiFtnsep),
287 						    evenIfAbsent, forcePar ) )
288 	{ LDEB(1); return -1;	}
289 
290     if  ( docRtfSaveDocumentTree( rw, "ftnsepc", &(bd->bdEiFtnsepc),
291 						    evenIfAbsent, forcePar ) )
292 	{ LDEB(1); return -1;	}
293 
294     if  ( docRtfSaveDocumentTree( rw, "ftncn", &(bd->bdEiFtncn),
295 						    evenIfAbsent, forcePar ) )
296 	{ LDEB(1); return -1;	}
297 
298     /******/
299 
300     if  ( docRtfSaveDocumentTree( rw, "aftnsep", &(bd->bdEiAftnsep),
301 						    evenIfAbsent, forcePar ) )
302 	{ LDEB(1); return -1;	}
303 
304     if  ( docRtfSaveDocumentTree( rw, "aftnsepc", &(bd->bdEiAftnsepc),
305 						    evenIfAbsent, forcePar ) )
306 	{ LDEB(1); return -1;	}
307 
308     if  ( docRtfSaveDocumentTree( rw, "aftncn", &(bd->bdEiAftncn),
309 						    evenIfAbsent, forcePar ) )
310 	{ LDEB(1); return -1;	}
311 
312     return 0;
313     }
314 
315 /************************************************************************/
316 /*									*/
317 /*  Determine the mask of scalar properties that differ from the	*/
318 /*  defaults.								*/
319 /*									*/
320 /************************************************************************/
321 
docRtfDocPropMask(PropertyMask * dpSaveMask,const DocumentProperties * dpDoc)322 int docRtfDocPropMask(	PropertyMask *			dpSaveMask,
323 			const DocumentProperties *	dpDoc )
324     {
325     int				rval= 0;
326 
327     PropertyMask		dpSetMask;
328     DocumentProperties		dpDef;
329 
330     const DocumentAttributeMap * const dam0= (const DocumentAttributeMap *)0;
331 
332     docInitDocumentProperties( &dpDef );
333 
334     utilPropMaskClear( &dpSetMask );
335     utilPropMaskFill( &dpSetMask, DPprop_COUNT );
336     utilPropMaskClear( dpSaveMask );
337 
338     if  ( docUpdDocumentProperties( dpSaveMask, &dpDef,
339 						    &dpSetMask, dpDoc, dam0 ) )
340 	{ LDEB(1); rval= -1; goto ready;	}
341 
342   ready:
343 
344     docCleanDocumentProperties( &dpDef );
345 
346     return rval;
347     }
348