1 /************************************************************************/
2 /*									*/
3 /*  Ted, Screen drawing and forcing drawing through			*/
4 /*									*/
5 /************************************************************************/
6 
7 #   include	"tedConfig.h"
8 
9 #   include	<stddef.h>
10 #   include	<stdlib.h>
11 #   include	<stdio.h>
12 
13 #   include	"tedApp.h"
14 #   include	"tedDraw.h"
15 #   include	"tedLayout.h"
16 #   include	<docTabStop.h>
17 #   include	<drawScreenFontUtil.h>
18 #   include	<geoGrid.h>
19 #   include	<docParaParticules.h>
20 #   include	<docNodeTree.h>
21 
22 #   include	<appDebugon.h>
23 
tedDrawParticuleLine(DrawingContext * dc,ScreenDrawingData * sdd,const BufferItem * paraNode,int head,int past,int textColorNr,int x0,int y0,int h)24 static void tedDrawParticuleLine(	DrawingContext *	dc,
25 					ScreenDrawingData *	sdd,
26 					const BufferItem *	paraNode,
27 					int			head,
28 					int			past,
29 					int			textColorNr,
30 					int			x0,
31 					int			y0,
32 					int			h )
33     {
34     const LayoutContext *	lc= &(dc->dcLayoutContext);
35     const TextParticule *	tp= paraNode->biParaParticules;
36     /*
37     DocumentPosition		dpHead;
38     PositionGeometry		pgHead;
39     */
40     DocumentPosition		dpTail;
41     PositionGeometry		pgTail;
42 
43     DocumentRectangle		drFill;
44 
45     docSetDocumentPosition( &dpTail, (BufferItem *)paraNode,
46 				tp[past- 1].tpStroff+ tp[past- 1].tpStrlen );
47     tedPositionGeometry( &pgTail, &dpTail, PARAfindFIRST, lc );
48 
49     drFill.drX0= x0;
50     drFill.drX1= pgTail.pgXPixels;
51     drFill.drY0= y0;
52     drFill.drY1= y0+ h- 1;
53 
54     if  ( drFill.drX1 > drFill.drX0 )
55 	{
56 	docDrawSetColorNumber( dc, (void *)sdd, textColorNr );
57 
58 	geoShiftRectangle( &drFill, -lc->lcOx, -lc->lcOy );
59 	drawFillRectangle( lc->lcDrawingSurface, &drFill );
60 	}
61 
62     return;
63     }
64 
tedDrawRunUnderline(const DrawTextLine * dtl,int part,int upto,int textAttrNr,const TextAttribute * ta,int x0Twips,int x1Twips,const LayoutPosition * baseLine)65 int tedDrawRunUnderline(		const DrawTextLine *	dtl,
66 					int			part,
67 					int			upto,
68 					int			textAttrNr,
69 					const TextAttribute *	ta,
70 					int			x0Twips,
71 					int			x1Twips,
72 					const LayoutPosition *	baseLine )
73     {
74     ScreenDrawingData *		sdd= (ScreenDrawingData *)dtl->dtlThrough;
75     DrawingContext *		dc= dtl->dtlDrawingContext;
76     const LayoutContext *	lc= &(dc->dcLayoutContext);
77 
78     const BufferItem *		paraNode= dtl->dtlParaNode;
79     const TextParticule *	tp= paraNode->biParaParticules;
80 
81     int				baselinePixels;
82     int				x0FrameShifted;
83     int				screenFont;
84     int				x0;
85     int				y0;
86     int				h;
87 
88     baselinePixels= docLayoutYPixels( lc, baseLine );
89     x0FrameShifted= docLayoutXPixels( lc,
90 	    dtl->dtlParagraphFrame->pfParaContentRect.drX0+ dtl->dtlXShift );
91 
92     screenFont= utilIndexMappingGet( lc->lcAttributeToScreenFont, textAttrNr );
93 
94     x0= x0FrameShifted+ tp[part].tpXContentXPixels;
95     drawFontUnderlineGeometry( &h, &y0,
96 			    lc->lcDrawingSurface, screenFont, baselinePixels );
97 
98     tedDrawParticuleLine( dc, sdd, paraNode, part, upto,
99 					ta->taTextColorNumber, x0, y0, h );
100 
101     return 0;
102     }
103 
tedDrawRunStrikethrough(const DrawTextLine * dtl,int part,int upto,int textAttrNr,const TextAttribute * ta,int x0Twips,int x1Twips,const LayoutPosition * baseLine)104 int tedDrawRunStrikethrough(	const DrawTextLine *	dtl,
105 					int			part,
106 					int			upto,
107 					int			textAttrNr,
108 					const TextAttribute *	ta,
109 					int			x0Twips,
110 					int			x1Twips,
111 					const LayoutPosition *	baseLine )
112     {
113     ScreenDrawingData *		sdd= (ScreenDrawingData *)dtl->dtlThrough;
114     DrawingContext *		dc= dtl->dtlDrawingContext;
115     const LayoutContext *	lc= &(dc->dcLayoutContext);
116 
117     const BufferItem *		paraNode= dtl->dtlParaNode;
118     const TextParticule *	tp= paraNode->biParaParticules;
119 
120     int				baselinePixels;
121     int				x0FrameShifted;
122     int				screenFont;
123     int				x0;
124     int				y0;
125     int				h;
126 
127     baselinePixels= docLayoutYPixels( lc, baseLine );
128     x0FrameShifted= docLayoutXPixels( lc,
129 	    dtl->dtlParagraphFrame->pfParaContentRect.drX0+ dtl->dtlXShift );
130 
131     screenFont= utilIndexMappingGet( lc->lcAttributeToScreenFont, textAttrNr );
132 
133     x0= x0FrameShifted+ tp[part].tpXContentXPixels;
134     drawFontStrikethroughGeometry( &h, &y0,
135 			    lc->lcDrawingSurface, screenFont, baselinePixels );
136 
137     tedDrawParticuleLine( dc, sdd, paraNode, part, upto,
138 					ta->taTextColorNumber, x0, y0, h );
139 
140     return 0;
141     }
142 
143 /************************************************************************/
144 /*									*/
145 /*  Draw a tab.								*/
146 /*									*/
147 /*  1)  Tabs need not to be drawn.					*/
148 /*									*/
149 /************************************************************************/
150 
tedDrawTab(const DrawTextLine * dtl,int part,int textAttrNr,const TextAttribute * ta,int leader,int x0Twips,int x1Twips,const LayoutPosition * baseLine)151 int tedDrawTab(		const DrawTextLine *		dtl,
152 			int				part,
153 			int				textAttrNr,
154 			const TextAttribute *		ta,
155 			int				leader,
156 			int				x0Twips,
157 			int				x1Twips,
158 			const LayoutPosition *		baseLine )
159     {
160     ScreenDrawingData *		sdd= (ScreenDrawingData *)dtl->dtlThrough;
161     DrawingContext *		dc= dtl->dtlDrawingContext;
162     const LayoutContext *	lc= &(dc->dcLayoutContext);
163     double			xfac= lc->lcPixelsPerTwip;
164     const BufferItem *		paraNode= dtl->dtlParaNode;
165     const TextParticule *	tp= paraNode->biParaParticules+ part;
166 
167     int				screenFont;
168 
169     int				pixelsWide;
170     int				pixelSize;
171     int				baselinePixels;
172     int				x0FrameShifted;
173 
174     DocumentRectangle		drSpan= dtl->dtlLineRectangle;
175 
176     baselinePixels= docLayoutYPixels( lc, baseLine );
177     x0FrameShifted= docLayoutXPixels( lc,
178 	    dtl->dtlParagraphFrame->pfParaContentRect.drX0+ dtl->dtlXShift );
179 
180     pixelsWide= COORDtoGRID( xfac, tp->tpTwipsWide );
181     drSpan.drX0= x0FrameShifted+ tp->tpXContentXPixels;
182     drSpan.drX1= x0FrameShifted+ tp->tpXContentXPixels+ pixelsWide- 1;
183 
184     if  ( dc->dcClipRect						&&
185 	  ! geoIntersectRectangle( (DocumentRectangle *)0,
186 					    dc->dcClipRect, &drSpan )	)
187 	{ return 0;	}
188 
189     screenFont= utilIndexMappingGet( lc->lcAttributeToScreenFont, textAttrNr );
190 
191     pixelSize= COORDtoGRID( xfac, 2* ta->taFontSizeHalfPoints );
192 
193     switch( leader )
194 	{
195 	case DOCtlNONE:
196 	    break;
197 
198 	case DOCtlDOTS:
199 
200 	    if  ( screenFont < 0 )
201 		{ LLDEB(textAttrNr,screenFont); return -1;	}
202 
203 	    drSpan.drX0 += pixelSize/ 4;
204 	    drSpan.drX1 -= pixelSize/ 2;
205 	    drSpan.drX0= 3* ( ( drSpan.drX0+ 2 )/ 3 );
206 
207 	    if  ( drSpan.drX1 <= drSpan.drX0 )
208 		{ return 0;	}
209 
210 	    if  ( ta->taFontIsBold )
211 		{
212 		static const unsigned char	boldDot[]= { 2, 1 };
213 
214 		drawSetLineAttributes( lc->lcDrawingSurface,
215 			2, LineStyleSingleDash, LineCapButt, LineJoinMiter,
216 			boldDot, sizeof( boldDot ) );
217 		}
218 	    else{
219 		static const unsigned char	dot[]= { 1, 2 };
220 
221 		drawSetLineAttributes( lc->lcDrawingSurface,
222 			1, LineStyleSingleDash, LineCapButt, LineJoinMiter,
223 			dot, sizeof( dot ) );
224 		}
225 
226 	    docDrawSetColorNumber( dc, sdd, ta->taTextColorNumber );
227 
228 	    drawLine( lc->lcDrawingSurface,
229 			    drSpan.drX0- lc->lcOx, baselinePixels- lc->lcOy,
230 			    drSpan.drX1- lc->lcOx, baselinePixels- lc->lcOy );
231 
232 	    break;
233 
234 	case DOCtlUNDERLINE:
235 	    if  ( screenFont < 0 )
236 		{ LLDEB(textAttrNr,screenFont); return -1;	}
237 
238 	    drSpan.drX0 += pixelSize/ 4;
239 	    drSpan.drX1 -= pixelSize/ 2;
240 	    if  ( drSpan.drX1 <= drSpan.drX0 )
241 		{ return 0;	}
242 
243 	    if  ( ta->taFontIsBold )
244 		{
245 		drawSetLineAttributes( lc->lcDrawingSurface,
246 				2, LineStyleSolid, LineCapButt, LineJoinMiter,
247 				(const unsigned char *)0, 0 );
248 		}
249 	    else{
250 		drawSetLineAttributes( lc->lcDrawingSurface,
251 				1, LineStyleSolid, LineCapButt, LineJoinMiter,
252 				(const unsigned char *)0, 0 );
253 		}
254 
255 	    docDrawSetColorNumber( dc, sdd, ta->taTextColorNumber );
256 
257 	    drawLine( lc->lcDrawingSurface,
258 			    drSpan.drX0- lc->lcOx, baselinePixels- lc->lcOy,
259 			    drSpan.drX1- lc->lcOx, baselinePixels- lc->lcOy );
260 
261 	    break;
262 
263 	case DOCtlHYPH:
264 	    if  ( screenFont < 0 )
265 		{ LLDEB(textAttrNr,screenFont); return -1;	}
266 
267 	    drSpan.drX0 += pixelSize/ 4;
268 	    drSpan.drX1 -= pixelSize/ 2;
269 	    drSpan.drX0= 7* ( ( drSpan.drX0+ 6 )/ 7 );
270 
271 	    if  ( drSpan.drX1 <= drSpan.drX0 )
272 		{ return 0;	}
273 
274 	    if  ( ta->taFontIsBold )
275 		{
276 		static const unsigned char	boldDash[]= { 4, 3 };
277 
278 		drawSetLineAttributes( lc->lcDrawingSurface,
279 			2, LineStyleSingleDash, LineCapButt, LineJoinMiter,
280 			boldDash, sizeof( boldDash ) );
281 		}
282 	    else{
283 		static const unsigned char	dash[]= { 3, 4 };
284 
285 		drawSetLineAttributes( lc->lcDrawingSurface,
286 			1, LineStyleSingleDash, LineCapButt, LineJoinMiter,
287 			dash, sizeof( dash ) );
288 		}
289 
290 	    docDrawSetColorNumber( dc, sdd, ta->taTextColorNumber );
291 
292 	    drawLine( lc->lcDrawingSurface,
293 			    drSpan.drX0- lc->lcOx, baselinePixels- lc->lcOy,
294 			    drSpan.drX1- lc->lcOx, baselinePixels- lc->lcOy );
295 
296 	    break;
297 
298 	case DOCtlTHICK:
299 	    LDEB(leader);
300 	    break;
301 	case DOCtlEQUAL:
302 	    LDEB(leader);
303 	    break;
304 	default:
305 	    LDEB(leader);
306 	    break;
307 	}
308 
309     return 0;
310     }
311 
312 /************************************************************************/
313 /*									*/
314 /*  Draw a footnote separator.						*/
315 /*									*/
316 /************************************************************************/
317 
tedDrawChftnsep(const DrawTextLine * dtl,int part,int textAttrNr,const TextAttribute * ta,int x0Twips,int x1Twips,const LayoutPosition * baseLine)318 int tedDrawChftnsep(	const DrawTextLine *		dtl,
319 			int				part,
320 			int				textAttrNr,
321 			const TextAttribute *		ta,
322 			int				x0Twips,
323 			int				x1Twips,
324 			const LayoutPosition *		baseLine )
325     {
326     ScreenDrawingData *		sdd= (ScreenDrawingData *)dtl->dtlThrough;
327     DrawingContext *		dc= dtl->dtlDrawingContext;
328     const LayoutContext *	lc= &(dc->dcLayoutContext);
329     double			xfac= lc->lcPixelsPerTwip;
330 
331     const BufferItem *		paraNode= dtl->dtlParaNode;
332     const TextParticule *	tp= paraNode->biParaParticules+ part;
333 
334     int				y0;
335     int				h;
336     int				baselinePixels;
337     int				pixelsWide;
338 
339     int				screenFont;
340     int				x0FrameShifted;
341     DocumentRectangle		drSpan= dtl->dtlLineRectangle;
342 
343     baselinePixels= docLayoutYPixels( lc, baseLine );
344     x0FrameShifted= docLayoutXPixels( lc,
345 	    dtl->dtlParagraphFrame->pfParaContentRect.drX0+ dtl->dtlXShift );
346 
347     pixelsWide= COORDtoGRID( xfac, tp->tpTwipsWide );
348     drSpan.drX0= x0FrameShifted+ tp->tpXContentXPixels;
349     drSpan.drX1= x0FrameShifted+ tp->tpXContentXPixels+ pixelsWide- 1;
350 
351     if  ( dc->dcClipRect						&&
352 	  ! geoIntersectRectangle( (DocumentRectangle *)0,
353 					    dc->dcClipRect, &drSpan )	)
354 	{ return 0;	}
355 
356     drawSetLineAttributes( lc->lcDrawingSurface,
357 			    1, LineStyleSolid, LineCapButt, LineJoinMiter,
358 			    (const unsigned char *)0, 0 );
359 
360     screenFont= utilIndexMappingGet( lc->lcAttributeToScreenFont, textAttrNr );
361     if  ( screenFont < 0 )
362 	{ LLDEB(textAttrNr,screenFont); return 0;	}
363 
364     drawFontStrikethroughGeometry( &h, &y0, lc->lcDrawingSurface,
365 						screenFont, baselinePixels );
366 
367     pixelsWide= COORDtoGRID( xfac, tp->tpTwipsWide );
368 
369     drSpan.drY0= y0;
370     drSpan.drY1= y0+ h- 1;
371 
372     docDrawSetColorNumber( dc, (void *)sdd, ta->taTextColorNumber );
373 
374     geoShiftRectangle( &drSpan, -lc->lcOx, -lc->lcOy );
375     drawFillRectangle( lc->lcDrawingSurface, &drSpan );
376 
377     return 0;
378     }
379 
380 /************************************************************************/
381 /*									*/
382 /*  Draw the individual segments of a smallcaps string.			*/
383 /*									*/
384 /************************************************************************/
385 
tedDrawSegments(DrawingContext * dc,int x,int y,int fullScreenFont,int scapsScreenFont,const char * s,const int * segments,int segmentCount)386 static void tedDrawSegments(	DrawingContext *	dc,
387 				int			x,
388 				int			y,
389 				int			fullScreenFont,
390 				int			scapsScreenFont,
391 				const char *		s,
392 				const int *		segments,
393 				int			segmentCount )
394     {
395     const LayoutContext *	lc= &(dc->dcLayoutContext);
396     int				seg;
397 
398     DocumentRectangle		drText;
399 
400     for ( seg= 0; seg < segmentCount; seg++ )
401 	{
402 	if  ( segments[2* seg+ 0] > 0 )
403 	    {
404 	    drawString( lc->lcDrawingSurface,
405 					x, y, fullScreenFont,
406 					s, segments[2* seg+ 0] );
407 
408 	    drawGetTextExtents( &drText, lc->lcDrawingSurface,
409 					x, y, fullScreenFont,
410 					s, segments[2* seg+ 0] );
411 
412 	    s += segments[2* seg+ 0];
413 	    x= drText.drX1+ 1;
414 	    }
415 
416 	if  ( segments[2* seg+ 1] > 0 )
417 	    {
418 	    drawString( lc->lcDrawingSurface,
419 					x, y, scapsScreenFont,
420 					s, segments[2* seg+ 1] );
421 
422 	    drawGetTextExtents( &drText, lc->lcDrawingSurface,
423 					x, y, scapsScreenFont,
424 					s, segments[2* seg+ 1] );
425 
426 	    s += segments[2* seg+ 1];
427 	    x= drText.drX1+ 1;
428 	    }
429 	}
430 
431     return;
432     }
433 
434 /************************************************************************/
435 
tedDrawSpan(const DrawTextLine * dtl,int part,int count,const LayoutPosition * baseLine,int textAttrNr,const TextAttribute * ta,const char * printString,int nbLen)436 int tedDrawSpan(	const DrawTextLine *		dtl,
437 			int				part,
438 			int				count,
439 			const LayoutPosition *		baseLine,
440 			int				textAttrNr,
441 			const TextAttribute *		ta,
442 			const char *			printString,
443 			int				nbLen )
444     {
445     int				rval= 0;
446 
447     ScreenDrawingData *		sdd= (ScreenDrawingData *)dtl->dtlThrough;
448     DrawingContext *		dc= dtl->dtlDrawingContext;
449     const LayoutContext *	lc= &(dc->dcLayoutContext);
450 
451     char *			upperString= (char *)0;
452     int *			segments= (int *)0;
453     int				segmentCount= 0;
454 
455     int				baselinePixels;
456     int				fullScreenFont;
457     int				y;
458 
459     int				x0FrameShifted;
460 
461     const BufferItem *		paraNode= dtl->dtlParaNode;
462     const TextLine *		tl= dtl->dtlTextLine;
463     const TextParticule *	tp= paraNode->biParaParticules+ part;
464 
465     int				spanX0;
466 
467     baselinePixels= docLayoutYPixels( lc, baseLine );
468     x0FrameShifted= docLayoutXPixels( lc,
469 	    dtl->dtlParagraphFrame->pfParaContentRect.drX0+ dtl->dtlXShift );
470     spanX0= x0FrameShifted+ tp->tpXContentXPixels;
471 
472     if  ( dc->dcClipRect						&&
473 	  part+ count < tl->tlFirstParticule+ tl->tlParticuleCount	)
474 	{
475 	const TextParticule *	tpp= paraNode->biParaParticules+ part+ count;
476 	DocumentRectangle	drSpan= dtl->dtlLineRectangle;
477 
478 	drSpan.drX0= spanX0;
479 	drSpan.drX1= x0FrameShifted+ tpp->tpXContentXPixels;
480 
481 	if  ( ! geoIntersectRectangle( (DocumentRectangle *)0,
482 					    dc->dcClipRect, &drSpan )	)
483 	    { return 0;	}
484 	}
485 
486     fullScreenFont= utilIndexMappingGet( lc->lcAttributeToScreenFont,
487 						    textAttrNr );
488     if  ( fullScreenFont < 0 )
489 	{ LLDEB(textAttrNr,fullScreenFont); rval= -1; goto ready;	}
490 
491     if  ( ta->taSmallCaps || ta->taCapitals )
492 	{
493 	if  ( docMakeCapsString( &upperString, &segments, &segmentCount,
494 						    ta, printString, nbLen ) )
495 	    { LDEB(nbLen); rval= -1; goto ready;	}
496 
497 	printString= upperString;
498 	}
499 
500     switch( ta->taSuperSub )
501 	{
502 	case TEXTvaSUPERSCRIPT:
503 	    drawFontGetSuperBaseline( &y, baselinePixels,
504 				    lc->lcDrawingSurface, fullScreenFont );
505 	    break;
506 
507 	case TEXTvaSUBSCRIPT:
508 	    drawFontGetSubBaseline( &y, baselinePixels,
509 				    lc->lcDrawingSurface, fullScreenFont );
510 	    break;
511 
512 	default:
513 	    LDEB(ta->taSuperSub);
514 	case TEXTvaREGULAR:
515 	    y= baselinePixels;
516 	    break;
517 	}
518 
519     docDrawSetFont( dc, (void *)sdd, textAttrNr, ta );
520     docDrawSetColorNumber( dc, (void *)sdd, ta->taTextColorNumber );
521 
522     if  ( ta->taSmallCaps && ! ta->taCapitals )
523 	{
524 	int	scapsScreenFont;
525 
526 	scapsScreenFont= docLayoutScapsScreenFont( lc, ta );
527 	if  ( scapsScreenFont < 0 )
528 	    { LDEB(scapsScreenFont); rval= -1; goto ready;	}
529 
530 	tedDrawSegments( dc, spanX0- lc->lcOx, y- lc->lcOy,
531 					fullScreenFont, scapsScreenFont,
532 					printString, segments, segmentCount );
533 	}
534     else{
535 	drawString( lc->lcDrawingSurface,
536 				spanX0- lc->lcOx, y- lc->lcOy,
537 					fullScreenFont, printString, nbLen );
538 	}
539 
540     /*
541     appDebug( "[%3d,%3d] -- %.*s\n", y, x0, len, printString );
542     */
543 
544   ready:
545 
546     if  ( upperString )
547 	{ free( upperString );	}
548     if  ( segments )
549 	{ free( segments );	}
550 
551     return rval;
552     }
553 
tedDrawTextLine(BufferItem * paraNode,int line,const ParagraphFrame * pf,const DocumentRectangle * drLine,void * vsdd,DrawingContext * dc,const BlockOrigin * bo)554 int tedDrawTextLine(		BufferItem *			paraNode,
555 				int				line,
556 				const ParagraphFrame *		pf,
557 				const DocumentRectangle *	drLine,
558 				void *				vsdd,
559 				DrawingContext *		dc,
560 				const BlockOrigin *		bo )
561     {
562     const TextLine *		tl= paraNode->biParaLines+ line;
563     int				part= tl->tlFirstParticule;
564     int				done;
565 
566     int				xTwips;
567     DrawTextLine		dtl;
568 
569     docInitDrawTextLine( &dtl );
570 
571     if  ( dc->dcClipRect						&&
572 	  ! geoIntersectRectangle( (DocumentRectangle *)0,
573 					    dc->dcClipRect, drLine )	)
574 	{ return tl->tlParticuleCount;	}
575 
576     docSetDrawTextLine( &dtl, vsdd, dc, tl, paraNode, bo, pf, drLine );
577     dtl.dtlDrawParticulesSeparately= 1;
578 
579     done= 0;
580     xTwips= pf->pfParaContentRect.drX0+ tl->tlLineIndent;
581     while( done < tl->tlParticuleCount )
582 	{
583 	int		drawn;
584 
585 	drawn= docDrawLineParticules( &dtl, &xTwips, part );
586 	if  ( drawn < 1 )
587 	    { LDEB(drawn); return -1;	}
588 
589 	done += drawn; part += drawn;
590 	}
591 
592     return done;
593     }
594 
595 /************************************************************************/
596 /*									*/
597 /*  Draw a rectangle to show that (part of) a line is selected.		*/
598 /*									*/
599 /*  1)  Delimit the line and calculate a preliminary rectangle for the	*/
600 /*	line.								*/
601 /*  2)  Table rectangle selections look nicer when we select the full	*/
602 /*	width of the table cell.					*/
603 /*  3)  Where to we start the selected rectangle? (left)		*/
604 /*  4)  Where to we end the selected rectangle? (right)			*/
605 /*  5)  Do the line and the selection overlap?				*/
606 /*	We do not have to consider I-Bar selections, so that is the	*/
607 /*	case if the selection begins before the end of the line and	*/
608 /*	ends after the begin of the line.				*/
609 /*	Include the line of an empty paragraph at either end of the	*/
610 /*	selection.							*/
611 /*  6)  Intersect with clipping rectangle.				*/
612 /*									*/
613 /************************************************************************/
614 
tedLineRectangle(DocumentRectangle * drRedraw,int * pInSelection,BufferItem * paraNode,DrawingContext * dc,ScreenDrawingData * sdd,int line,const DocumentRectangle * drParaContent)615 static int tedLineRectangle(	DocumentRectangle *		drRedraw,
616 				int *				pInSelection,
617 				BufferItem *			paraNode,
618 				DrawingContext *		dc,
619 				ScreenDrawingData *		sdd,
620 				int				line,
621 				const DocumentRectangle *	drParaContent )
622     {
623     const LayoutContext *	lc= &(dc->dcLayoutContext);
624     const DocumentSelection *	ds= dc->dcSelection;
625     const SelectionGeometry *	sg= dc->dcSelectionGeometry;
626 
627     DocumentSelection	dsLine;
628     SelectionGeometry	sgLine;
629 
630     const int		lastLine= 0;
631     DocumentRectangle	drLine;
632 
633     int			tableRectangle;
634     int			cmp_ShLh;
635     int			cmp_StLh;
636     int			cmp_ShLt;
637     int			cmp_StLt;
638     int			is_StPh;
639     int			is_ShPt;
640 
641     int			partLineBegin;
642     int			partLineEnd;
643 
644     int			inSelection= 0;
645 
646     if  ( ! docSelectionSameRoot( ds, paraNode ) )
647 	{ return 0;	}
648 
649     /*  1  */
650     docLineSelection( &dsLine, &partLineBegin, &partLineEnd, paraNode, line );
651     tedSelectionGeometry( &sgLine, &dsLine,
652 		docGetBodySectNode( paraNode, lc->lcDocument ), lastLine, lc );
653 
654     if  ( sgLine.sgHead.pgLine != line )
655 	{ LLDEB(sgLine.sgHead.pgLine,line);	}
656     if  ( sgLine.sgTail.pgLine != line )
657 	{ LLDEB(sgLine.sgTail.pgLine,line);	}
658 
659     drLine= sgLine.sgRectangle;
660 
661     /*  2  */
662     tableRectangle= 0;
663     if  ( ds->dsCol0 >= 0						&&
664 	  ds->dsCol1 >= 0						&&
665 	  ! docPositionsInsideCell( &(ds->dsHead), &(ds->dsTail) )	)
666 	{ tableRectangle= 1; }
667 
668     cmp_ShLh= docComparePositions( &(ds->dsHead), &(dsLine.dsHead) );
669     cmp_StLh= docComparePositions( &(ds->dsTail), &(dsLine.dsHead) );
670     cmp_ShLt= docComparePositions( &(ds->dsHead), &(dsLine.dsTail) );
671     cmp_StLt= docComparePositions( &(ds->dsTail), &(dsLine.dsTail) );
672 
673     is_StPh= ( sg->sgTail.pgPositionFlags & POSflagPARA_HEAD ) != 0;
674     is_ShPt= ( sg->sgHead.pgPositionFlags & POSflagPARA_TAIL ) != 0;
675 
676     /*  3  */
677     if  ( cmp_ShLh <= 0 || ( cmp_ShLh == 0 && tableRectangle ) )
678 	{
679 	int	x0Twips= drParaContent->drX0;
680 
681 	if  ( paraNode->biParaFirstIndentTwips < 0 )
682 	    { x0Twips += paraNode->biParaFirstIndentTwips;	}
683 
684 	drLine.drX0= docLayoutXPixels( lc, x0Twips );
685 
686 	if  ( cmp_ShLh == 0 )
687 	    {
688 	    x0Twips= drParaContent->drX0;
689 
690 	    if  ( line == 0 )
691 		{ x0Twips += paraNode->biParaFirstIndentTwips;	}
692 
693 	    drLine.drX0= docLayoutXPixels( lc, x0Twips );
694 	    }
695 	}
696     else{ drLine.drX0= sg->sgHead.pgXPixels;	}
697 
698     /*  4  */
699     if  ( cmp_StLt > 0 || ( cmp_StLt == 0 && tableRectangle ) )
700 	{ drLine.drX1= docLayoutXPixels( lc, drParaContent->drX1 );	}
701     else{ drLine.drX1= sg->sgTail.pgXPixels;				}
702 
703     /*  5  */
704     inSelection= 0;
705 
706     if  ( docParaStrlen( ds->dsTail.dpNode ) == 0	&&
707 	  cmp_StLh == 0					)
708 	{ cmp_StLh=  1;	}
709     if  ( docParaStrlen( ds->dsHead.dpNode ) == 0	&&
710 	  cmp_ShLt == 0					)
711 	{ cmp_ShLt= -1;	}
712 
713     if  ( ( cmp_ShLt <  0 && cmp_StLh > 0 )		|| /* Overlap	   */
714 	  ( cmp_ShLt <= 0 && cmp_StLt > 0 && is_ShPt )	|| /* head at tail */
715 	  ( cmp_StLh <= 0 && cmp_ShLh < 0 && is_StPh )	)  /* tail at head */
716 	{ inSelection= 1;	}
717 
718     /*  Highlight tail of selection at line head  */
719     if  ( ( cmp_StLh == 0 && cmp_ShLh < 0 )	)	/* tail at head	*/
720 	{ drLine.drX0 -= 3;	}
721 
722     /*  6  */
723     if  ( ! dc->dcClipRect						||
724 	  geoIntersectRectangle( drRedraw, dc->dcClipRect, &drLine )	)
725 	{ *pInSelection= inSelection; return 1;	}
726     else{ return 0;	}
727     }
728 
tedDrawTextReverse(BufferItem * paraNode,int line,const ParagraphFrame * pf,const DocumentRectangle * drLine,void * vsdd,DrawingContext * dc,const BlockOrigin * bo)729 int tedDrawTextReverse(		BufferItem *			paraNode,
730 				int				line,
731 				const ParagraphFrame *		pf,
732 				const DocumentRectangle *	drLine,
733 				void *				vsdd,
734 				DrawingContext *		dc,
735 				const BlockOrigin *		bo )
736     {
737     const LayoutContext *	lc= &(dc->dcLayoutContext);
738     ScreenDrawingData *		sdd= (ScreenDrawingData *)vsdd;
739 
740     DocumentRectangle		drRedraw;
741     int				done;
742     int				inSelection;
743 
744     if  ( tedLineRectangle( &drRedraw, &inSelection, paraNode, dc, sdd, line,
745 						    &(pf->pfParaContentRect) ) )
746 	{
747 	geoShiftRectangle( &drRedraw, -lc->lcOx, -lc->lcOy );
748 	drawSetClipRect( lc->lcDrawingSurface, &drRedraw );
749 
750 	done= tedDrawTextLine( paraNode, line, pf, drLine, vsdd, dc, bo );
751 
752 	tedOriginalClipping( dc, sdd );
753 	}
754     else{
755 	TextLine *	tl= paraNode->biParaLines+ line;
756 
757 	done= tl->tlParticuleCount;
758 	}
759 
760     return done;
761     }
762 
tedDrawTextSelected(BufferItem * paraNode,int line,const ParagraphFrame * pf,const DocumentRectangle * drLine,void * vsdd,DrawingContext * dc,const BlockOrigin * bo)763 int tedDrawTextSelected(	BufferItem *			paraNode,
764 				int				line,
765 				const ParagraphFrame *		pf,
766 				const DocumentRectangle *	drLine,
767 				void *				vsdd,
768 				DrawingContext *		dc,
769 				const BlockOrigin *		bo )
770     {
771     const LayoutContext *	lc= &(dc->dcLayoutContext);
772     ScreenDrawingData *		sdd= (ScreenDrawingData *)vsdd;
773 
774     DocumentRectangle		drRedraw;
775     int				done;
776     int				inSelection;
777 
778     if  ( tedLineRectangle( &drRedraw, &inSelection, paraNode, dc, sdd, line,
779 						    &(pf->pfParaContentRect) ) )
780 	{
781 	geoShiftRectangle( &drRedraw, -lc->lcOx, -lc->lcOy );
782 	drawSetClipRect( lc->lcDrawingSurface, &drRedraw );
783 
784 	if  ( inSelection )
785 	    {
786 	    docDrawSetColorRgb( dc, (void *)sdd, &(sdd->sddBehindColor) );
787 	    drawFillRectangle( lc->lcDrawingSurface, &drRedraw );
788 	    }
789 
790 	done= tedDrawTextLine( paraNode, line, pf, drLine, vsdd, dc, bo );
791 
792 	tedOriginalClipping( dc, sdd );
793 	}
794     else{
795 	TextLine *	tl= paraNode->biParaLines+ line;
796 
797 	done= tl->tlParticuleCount;
798 	}
799 
800     return done;
801     }
802 
803