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