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