1 /************************************************************************/
2 /*									*/
3 /*  Manage text attributes while saving an RTF file.			*/
4 /*									*/
5 /************************************************************************/
6 
7 #   include	"docRtfConfig.h"
8 
9 #   include	<stdlib.h>
10 #   include	<stdio.h>
11 #   include	<ctype.h>
12 
13 #   include	<appDebugon.h>
14 
15 #   include	<uniUtf8.h>
16 #   include	<utilMatchFont.h>
17 #   include	<psShading.h>
18 #   include	"docRtfWriterImpl.h"
19 #   include	"docRtfFlags.h"
20 #   include	"docRtfTags.h"
21 #   include	<textConverter.h>
22 
23 /************************************************************************/
24 /*									*/
25 /*  Save a text attribute (change).					*/
26 /*									*/
27 /************************************************************************/
28 
docRtfSaveTextAttributeImpl(RtfWriter * rw,const PropertyMask * updMask,const TextAttribute * ta)29 static void docRtfSaveTextAttributeImpl(	RtfWriter *		rw,
30 						const PropertyMask *	updMask,
31 						const TextAttribute *	ta )
32     {
33     if  ( PROPmaskISSET( updMask, TApropTEXT_STYLE ) )
34 	{ docRtfWriteArgTag( rw, "cs", ta->taTextStyleNumber ); }
35 
36     if  ( PROPmaskISSET( updMask, TApropFONT_NUMBER ) )
37 	{ docRtfWriteArgTag( rw, "f", ta->taFontNumber ); }
38 
39     if  ( PROPmaskISSET( updMask, TApropFONTSIZE ) )
40 	{ docRtfWriteArgTag( rw, "fs", ta->taFontSizeHalfPoints ); }
41 
42     if  ( PROPmaskISSET( updMask, TApropTEXT_COLOR ) )
43 	{ docRtfWriteArgTag( rw, "cf", ta->taTextColorNumber ); }
44 
45     if  ( PROPmaskISSET( updMask, TApropBORDER ) )
46 	{
47 	const int	anyway= 1;
48 
49 	docRtfSaveBorderByNumber( rw, "chbrdr",
50 					    ta->taBorderNumber, anyway );
51 	}
52 
53     if  ( PROPmaskISSET( updMask, TApropSHADING ) )
54 	{
55 	const BufferDocument *		bd= rw->rwDocument;
56 	ItemShading			is;
57 
58 	docGetItemShadingByNumber( &is, bd, ta->taShadingNumber );
59 
60 	if  ( is.isBackColor > 0		&&
61 	      is.isPattern == DOCspSOLID	&&
62 	      is.isLevel == 0			)
63 	    { docRtfWriteArgTag( rw, "cb", is.isBackColor );	}
64 
65 	docRtfSaveShadingByNumber( rw, ta->taShadingNumber,
66 		DOCrtf_TextShadingTags, DOCrtf_TextShadingTagCount,
67 		"chcfpat", "chcbpat", "chshdng" );
68 	}
69 
70     if  ( PROPmaskISSET( updMask, TApropFONTBOLD ) )
71 	{ docRtfWriteFlagTag( rw, "b", ta->taFontIsBold );	}
72 
73     if  ( PROPmaskISSET( updMask, TApropFONTSLANTED ) )
74 	{ docRtfWriteFlagTag( rw, "i", ta->taFontIsSlanted );	}
75 
76     if  ( PROPmaskISSET( updMask, TApropTEXTUNDERLINED ) )
77 	{ docRtfWriteFlagTag( rw, "ul", ta->taTextIsUnderlined );	}
78 
79     if  ( PROPmaskISSET( updMask, TApropSUPERSUB ) )
80 	{
81 	docRtfWriteEnumTag( rw, DOCrtf_SupersubTags, ta->taSuperSub,
82 				    DOCrtf_SupersubTagCount, TEXTva_COUNT );
83 	}
84 
85     if  ( PROPmaskISSET( updMask, TApropBASELINE_SHIFT ) )
86 	{
87 	if  ( ta->taBaselineShiftHalfPoints >= 0 )
88 	    { docRtfWriteArgTag( rw, "up",  ta->taBaselineShiftHalfPoints ); }
89 	else{ docRtfWriteArgTag( rw, "dn", -ta->taBaselineShiftHalfPoints ); }
90 	}
91 
92     if  ( PROPmaskISSET( updMask, TApropSMALLCAPS ) )
93 	{ docRtfWriteFlagTag( rw, "scaps", ta->taSmallCaps );	}
94 
95     if  ( PROPmaskISSET( updMask, TApropCAPITALS ) )
96 	{ docRtfWriteFlagTag( rw, "caps", ta->taCapitals );	}
97 
98     if  ( PROPmaskISSET( updMask, TApropSTRIKETHROUGH ) )
99 	{ docRtfWriteFlagTag( rw, "strike", ta->taHasStrikethrough );	}
100 
101     return;
102     }
103 
docRtfSaveTextAttribute(RtfWriter * rw,const PropertyMask * updMask,const TextAttribute * taDoc)104 void docRtfSaveTextAttribute(		RtfWriter *		rw,
105 					const PropertyMask *	updMask,
106 					const TextAttribute *	taDoc )
107     {
108     TextAttribute	taFile= *taDoc;
109 
110     if  ( ! ( rw->rwSaveFlags & RTFflagUNENCODED )		&&
111 	  PROPmaskISSET( updMask, TApropFONT_NUMBER )	)
112 	{
113 	const DocumentProperties *	dp= &(rw->rwDocument->bdProperties);
114 	const DocumentFontList *	dfl= dp->dpFontList;
115 	const DocumentFont *		df;
116 
117 	df= docFontListGetFontByNumber( dfl, taFile.taFontNumber );
118 	if  ( df )
119 	    {
120 	    int			fileFontNumber;
121 	    int			charset= FONTcharsetDEFAULT;
122 	    const int		symbol= ' ';
123 
124 	    fileFontNumber= docRtfWriteGetCharset( rw, &charset, df, symbol );
125 	    if  ( fileFontNumber < 0 )
126 		{ SLXDEB(df->dfName,fileFontNumber,symbol);	}
127 	    else{ taFile.taFontNumber= fileFontNumber;		}
128 	    }
129 	}
130 
131     docRtfSaveTextAttributeImpl( rw, updMask, &taFile );
132     }
133 
134 /************************************************************************/
135 /*									*/
136 /*  Finish/Begin writing a destination.					*/
137 /*									*/
138 /************************************************************************/
139 
docRtfPopAttribute(RtfWriter * rw)140 int docRtfPopAttribute(		RtfWriter *	rw )
141     {
142     PushedAttribute *	pa;
143 
144     pa= rw->rwcPushedAttribute;
145     if  ( ! pa )
146 	{ XDEB(pa); return -1;	}
147 
148     rw->rwTextAttribute= pa->paTextAttribute;
149     rw->rwTextCharset= pa->paTextCharset;
150     rw->rwcPushedAttribute= pa->paNext;
151 
152     free( pa );
153 
154     return 0;
155     }
156 
docRtfPushAttribute(RtfWriter * rw)157 int docRtfPushAttribute(		RtfWriter *	rw )
158     {
159     PushedAttribute *		pa;
160 
161     pa= (PushedAttribute *)malloc( sizeof( PushedAttribute ) );
162     if  ( ! pa )
163 	{ XDEB(pa); return- 1;	}
164     pa->paNext= rw->rwcPushedAttribute;
165     rw->rwcPushedAttribute= pa;
166     pa->paTextAttribute= rw->rwTextAttribute;
167     pa->paTextCharset= rw->rwTextCharset;
168 
169     return 0;
170     }
171 
172 /************************************************************************/
173 /*									*/
174 /*  Reset the text attribute.						*/
175 /*									*/
176 /************************************************************************/
177 
docRtfWriteSwitchToPlain(RtfWriter * rw)178 void docRtfWriteSwitchToPlain(		RtfWriter *	rw )
179     {
180     /*  1  */
181     docPlainTextAttribute( &(rw->rwTextAttribute), rw->rwDocument );
182     rw->rwTextCharset= FONTcharsetANSI;
183 
184     /*  2  */
185     docRtfWriteTag( rw, RTFtag_plain );
186     }
187 
188 /************************************************************************/
189 /*									*/
190 /*  Switch text attributes.						*/
191 /*									*/
192 /************************************************************************/
193 
docRtfWriteSwitchTextAttributes(RtfWriter * rw,int textAttrNr,const char * first)194 void docRtfWriteSwitchTextAttributes(	RtfWriter *		rw,
195 					int			textAttrNr,
196 					const char *		first )
197     {
198     const BufferDocument *	bd= rw->rwDocument;
199     TextAttribute		ta;
200 
201     int				symbol= ' ';
202 
203     if  ( first )
204 	{
205 	unsigned short	uni;
206 	int		step= uniGetUtf8( &uni, first );
207 
208 	if  ( step > 1 )
209 	    { symbol= uni;	}
210 	}
211 
212     docGetTextAttributeByNumber( &ta, bd, textAttrNr );
213 
214     if  ( ta.taFontNumber >= 0 )
215 	{
216 	const DocumentProperties *	dp= &(bd->bdProperties);
217 	const DocumentFontList *	dfl= dp->dpFontList;
218 
219 	PropertyMask			taSetMask;
220 	PropertyMask			doneMask;
221 
222 	utilPropMaskClear( &taSetMask );
223 	utilPropMaskFill( &taSetMask, TAprop_COUNT );
224 
225 	utilPropMaskClear( &doneMask );
226 	utilUpdateTextAttribute( &doneMask, &(rw->rwTextAttribute),
227 							    &taSetMask, &ta );
228 	if  ( PROPmaskISSET( &doneMask, TApropSHADING ) )
229 	    {
230 	    if  ( ! docShadingNumberIsShading( bd, ta.taShadingNumber ) )
231 		{
232 		docRtfWriteTag( rw, RTFtag_plain );
233 		utilInitTextAttribute( &(rw->rwTextAttribute) );
234 		utilPropMaskClear( &doneMask );
235 		utilUpdateTextAttribute( &doneMask, &(rw->rwTextAttribute),
236 							    &taSetMask, &ta );
237 		}
238 	    }
239 
240 	if  ( ! ( rw->rwSaveFlags & RTFflagUNENCODED ) )
241 	    {
242 	    const DocumentFont *		df;
243 
244 	    df= docFontListGetFontByNumber( dfl, ta.taFontNumber );
245 	    if  ( df )
246 		{
247 		int			fileFontNumber;
248 		int			charset= FONTcharsetDEFAULT;
249 		const char *		encodingName= (const char *)0;
250 
251 		fileFontNumber= docRtfWriteGetCharset( rw,
252 						&charset, df, symbol );
253 		if  ( fileFontNumber < 0 )
254 		    { SLXDEB(df->dfName,fileFontNumber,symbol);	}
255 		else{ ta.taFontNumber= fileFontNumber;		}
256 
257 		if  ( rw->rwTextCharset != charset )
258 		    {
259 		    rw->rwTextCharset= charset;
260 		    PROPmaskADD( &doneMask, TApropFONT_NUMBER );
261 		    }
262 
263 		encodingName= utilGetEncodingName( df->dfName, charset );
264 		textConverterSetNativeEncodingName(
265 				    rw->rwTextTextConverter, encodingName );
266 		}
267 	    }
268 
269 	if  ( ! utilPropMaskIsEmpty( &doneMask ) )
270 	    { docRtfSaveTextAttributeImpl( rw, &doneMask, &ta );	}
271 	}
272 
273     return;
274     }
275 
276