1 /************************************************************************/
2 /* */
3 /* Ted: Manipulation of font and text attributes. */
4 /* */
5 /************************************************************************/
6
7 # include "docBufConfig.h"
8
9 # include <stddef.h>
10 # include <ctype.h>
11
12 # include "docBuf.h"
13 # include "docNodeTree.h"
14 # include "docParaParticules.h"
15 # include <docListLevel.h>
16
17 # include <appDebugon.h>
18
19 /************************************************************************/
20 /* */
21 /* Get font properties of the current position. */
22 /* */
23 /************************************************************************/
24
docGetPositionAttributes(PropertyMask * pUpdMask,TextAttribute * pTaNew,const BufferDocument * bd,const TextParticule * tp)25 static int docGetPositionAttributes(
26 PropertyMask * pUpdMask,
27 TextAttribute * pTaNew,
28 const BufferDocument * bd,
29 const TextParticule * tp )
30 {
31 TextAttribute ta;
32
33 docGetTextAttributeByNumber( &ta, bd, tp->tpTextAttrNr );
34
35 *pTaNew= ta;
36
37 if ( pUpdMask )
38 {
39 utilPropMaskClear( pUpdMask );
40 utilPropMaskFill( pUpdMask, TAprop_COUNT );
41 }
42
43 return tp->tpTextAttrNr;
44 }
45
46 /************************************************************************/
47 /* */
48 /* Get font properties of a text particule. Use the aatributes of the */
49 /* list for particules in a list text field. */
50 /* */
51 /************************************************************************/
52
docGetEffectiveTextAttributes(TextAttribute * ta,BufferDocument * bd,const BufferItem * paraNode,int part)53 int docGetEffectiveTextAttributes(
54 TextAttribute * ta,
55 BufferDocument * bd,
56 const BufferItem * paraNode,
57 int part )
58 {
59 const TextParticule * tp= paraNode->biParaParticules+ part;
60 int textAttrNr= tp->tpTextAttrNr;
61
62 docGetTextAttributeByNumber( ta, bd, tp->tpTextAttrNr );
63
64 if ( paraNode->biParaListOverride > 0 )
65 {
66 DocumentSelection dsInside;
67 DocumentSelection dsAround;
68 int headPart;
69 int tailPart;
70
71 if ( ! docDelimitParaHeadField( (DocumentField **)0,
72 &dsInside, &dsAround,
73 &headPart, &tailPart, paraNode, bd ) &&
74 part > headPart &&
75 part < tailPart )
76 {
77 const ListLevel * ll;
78
79 if ( docGetListLevelOfParagraph( (int *)0, (int *)0,
80 (struct ListOverride **)0, (struct DocumentList **)0, &ll,
81 &(paraNode->biParaProperties), bd ) )
82 { LDEB(1); }
83 else{
84 PropertyMask taSetMask;
85
86 taSetMask= ll->llTextAttributeMask;
87
88 if ( ll->llFollow != DOCllfNONE &&
89 part == tailPart- 1 &&
90 ( PROPmaskISSET( &taSetMask, TApropTEXTUNDERLINED ) ||
91 PROPmaskISSET( &taSetMask, TApropSTRIKETHROUGH ) ) )
92 {
93 PROPmaskUNSET( &taSetMask, TApropTEXTUNDERLINED );
94 PROPmaskUNSET( &taSetMask, TApropSTRIKETHROUGH );
95 }
96
97 utilUpdateTextAttribute( (PropertyMask *)0, ta,
98 &taSetMask, &(ll->llTextAttribute) );
99
100 textAttrNr= docTextAttributeNumber( bd, ta );
101 }
102 }
103 }
104
105 return textAttrNr;
106 }
107
108 /************************************************************************/
109 /* */
110 /* Get the common text properties of the current selection. */
111 /* */
112 /* Remember the text attribute of the beginning of the selection. */
113 /* */
114 /* NOTE that for I-Bar selections, in case of ambiguity, there is a */
115 /* */
116 /* preference for the attribute of the particule before the */
117 /* current position. */
118 /* 1) Get the last particule number for the beginning of the */
119 /* selection. */
120 /* 2) If the paragraph is part of a list, exclude the bullet from */
121 /* the selection. */
122 /* */
123 /************************************************************************/
124
docGetSelectionAttributes(BufferDocument * bd,const DocumentSelection * ds,PropertyMask * pUpdMask,TextAttribute * ta)125 int docGetSelectionAttributes( BufferDocument * bd,
126 const DocumentSelection * ds,
127 PropertyMask * pUpdMask,
128 TextAttribute * ta )
129 {
130 BufferItem * paraNode;
131 int part;
132 const TextParticule * tp;
133 int textAttrNr;
134
135 TextAttribute taNew;
136 PropertyMask updMask;
137
138 int bulletPartBegin= -1;
139 int bulletPartEnd= -1;
140
141 int returnBullet= 0;
142 int IBar= docIsIBarSelection( ds );
143 int flags;
144
145 paraNode= ds->dsHead.dpNode;
146
147 /* 1 */
148 if ( docFindParticuleOfPosition( &part, &flags,
149 &(ds->dsHead), PARAfindLAST ) )
150 {
151 LDEB(ds->dsHead.dpStroff);
152 utilPropMaskClear( pUpdMask );
153 return -1;
154 }
155
156 /* 2 */
157 if ( paraNode->biParaListOverride > 0 )
158 {
159 DocumentField * dfBullet= (DocumentField *)0;
160 DocumentSelection dsInsideBullet;
161 DocumentSelection dsAroundBullet;
162
163 if ( docDelimitParaHeadField( &dfBullet,
164 &dsInsideBullet, &dsAroundBullet,
165 &bulletPartBegin, &bulletPartEnd,
166 paraNode, bd ) )
167 { LDEB(1); }
168
169 if ( part <= bulletPartEnd )
170 {
171 if ( ! docSelectionInsideParagraph( ds ) ||
172 ds->dsTail.dpStroff >= dsAroundBullet.dsTail.dpStroff )
173 { part= bulletPartEnd+ 1; }
174 else{ returnBullet= 1; }
175 }
176 }
177
178 tp= paraNode->biParaParticules+ part;
179
180 if ( IBar &&
181 part > 0 &&
182 ( flags & POSflagPART_HEAD ) &&
183 tp[-1].tpKind == DOCkindSPAN )
184 { tp--; part--; }
185
186 textAttrNr= docGetPositionAttributes( &updMask, &taNew, bd, tp );
187
188 if ( IBar || returnBullet )
189 {
190 *pUpdMask= updMask;
191 *ta= taNew;
192 return textAttrNr;
193 }
194
195 utilPropMaskClear( &updMask );
196
197 for (;;)
198 {
199 int col;
200
201 col= paraNode->biParent->biNumberInParent;
202
203 if ( ds->dsCol0 < 0 ||
204 ds->dsCol1 < 0 ||
205 ( col >= ds->dsCol0 && col <= ds->dsCol1 ) )
206 {
207 while( part < paraNode->biParaParticuleCount )
208 {
209 PropertyMask pm;
210 PropertyMask pmAll;
211
212 TextAttribute ta;
213
214 if ( paraNode == ds->dsTail.dpNode &&
215 tp->tpStroff >= ds->dsTail.dpStroff )
216 { break; }
217
218 docGetTextAttributeByNumber( &ta, bd, tp->tpTextAttrNr );
219
220 utilPropMaskClear( &pm );
221
222 utilPropMaskClear( &pmAll );
223 utilPropMaskFill( &pmAll, TAprop_COUNT );
224
225 utilAttributeDifference( &pm, &taNew, &pmAll, &ta );
226
227 utilPropMaskOr( &updMask, &updMask, &pm );
228
229 tp++; part++;
230 }
231 }
232
233 if ( paraNode == ds->dsTail.dpNode )
234 { break; }
235
236 paraNode= docNextParagraph( paraNode );
237 if ( ! paraNode )
238 { break; }
239
240 part= 0;
241 tp= paraNode->biParaParticules+ part;
242
243 /* 2 */
244 if ( paraNode->biParaListOverride > 0 )
245 {
246 DocumentField * dfBullet= (DocumentField *)0;
247 DocumentSelection dsInsideBullet;
248 DocumentSelection dsAroundBullet;
249
250 if ( docDelimitParaHeadField( &dfBullet,
251 &dsInsideBullet, &dsAroundBullet,
252 &bulletPartBegin, &bulletPartEnd,
253 paraNode, bd ) )
254 { LDEB(1); }
255
256 part= bulletPartEnd+ 1;
257 tp= paraNode->biParaParticules+ part;
258 }
259 }
260
261 utilPropMaskNot( &updMask, &updMask );
262
263 *pUpdMask= updMask;
264 *ta= taNew;
265
266 return textAttrNr;
267 }
268
269