1 /************************************************************************/
2 /*									*/
3 /*  Ted: screen specific shape drawing.					*/
4 /*									*/
5 /************************************************************************/
6 
7 #   include	"tedConfig.h"
8 
9 #   include	<stddef.h>
10 #   include	<stdlib.h>
11 
12 #   include	<docScreenLayout.h>
13 #   include	"tedDraw.h"
14 #   include	<geoGrid.h>
15 #   include	<docShape.h>
16 #   include	<docDrawShapeArrow.h>
17 
18 #   include	<appDebugon.h>
19 
20 /************************************************************************/
21 /*									*/
22 /*  Draw a Word 97+ drawing shape.					*/
23 /*									*/
24 /************************************************************************/
25 
tedShapeDrawArrowHead(const LayoutContext * lc,int widthPixels,const DrawShapeArrow * dsa)26 static int tedShapeDrawArrowHead(	const LayoutContext *	lc,
27 					int			widthPixels,
28 					const DrawShapeArrow *	dsa )
29     {
30     const ShapeArrow *	sa= &(dsa->dsaArrow);
31     DrawingSurface	ds= lc->lcDrawingSurface;
32     Point2DI		points[7];
33     Arc2DI		arc;
34 
35     switch( sa->saArrowHead )
36 	{
37 	int	i;
38 
39 	case DSarrowNONE:
40 	    break;
41 
42 	case DSarrowARROW:
43 	case DSarrowSTEALTH_ARROW:
44 	case DSarrowDIAMOND:
45 	    for ( i= 0; i <= dsa->dsaPathLength; i++ )
46 		{
47 		points[i].x= dsa->dsaPath[i].x;
48 		points[i].y= dsa->dsaPath[i].y;
49 		}
50 	    drawFillPolygon( ds, points, dsa->dsaPathLength );
51 	    break;
52 
53 	case DSarrowOPEN_ARROW:
54 	    for ( i= 0; i <= dsa->dsaPathLength; i++ )
55 		{
56 		points[i].x= dsa->dsaPath[i].x;
57 		points[i].y= dsa->dsaPath[i].y;
58 		}
59 
60 	    drawSetLineAttributes( ds,
61 		    widthPixels, LineStyleSolid, LineCapButt, LineJoinMiter,
62 		    (unsigned char *)0, 0 );
63 
64 	    drawLines( ds, points, dsa->dsaPathLength, 0 );
65 	    break;
66 
67 	case DSarrowOVAL:
68 	    arc.a2diRect.drX0= dsa->dsaArrowRectangle.x0;
69 	    arc.a2diRect.drY0= dsa->dsaArrowRectangle.y0;
70 	    arc.a2diRect.drX1= dsa->dsaArrowRectangle.x1;
71 	    arc.a2diRect.drY1= dsa->dsaArrowRectangle.y1;
72 
73 	    geoNormalizeRectangle( &(arc.a2diRect), &(arc.a2diRect) );
74 	    arc.a2diAngleFrom= 64* 0;
75 	    arc.a2diAngleStep= 64* 360;
76 
77 	    drawFillArc( ds, &arc );
78 	    break;
79 
80 	case DSarrowCHEVRON_ARROW:
81 	case DSarrow2CHEVRON_ARROW:
82 	default:
83 	    LDEB(sa->saArrowHead); break;
84 	}
85 
86     return 0;
87     }
88 
tedDrawGetVertices(const DocumentRectangle * drTwips,const DrawingShape * ds,const LayoutContext * lc,ScreenDrawingData * sdd)89 static Point2DI * tedDrawGetVertices(
90 				const DocumentRectangle *	drTwips,
91 				const DrawingShape *		ds,
92 				const LayoutContext *		lc,
93 				ScreenDrawingData *		sdd )
94     {
95     const ShapeDrawing *	sd= &(ds->dsDrawing);
96     double			xfac= lc->lcPixelsPerTwip;
97     int				x0Ref= drTwips->drX0;
98     int				y0Ref= drTwips->drY0;
99 
100     int				i;
101     const Point2DI *		sv;
102 
103     Point2DI *			xp;
104     Point2DI *			xpret;
105 
106     xp= xpret= malloc( ( sd->sdVertexCount+ 1)* sizeof(Point2DI) );
107     if  ( ! xp )
108 	{ LXDEB(sd->sdVertexCount,xp); return (Point2DI *)0;	}
109 
110     sv= sd->sdVertices;
111     for ( i= 0; i < sd->sdVertexCount; xp++, sv++, i++ )
112 	{
113 	xp->x= docLayoutXPixels( lc, x0Ref+ sv->x )- lc->lcOx;
114 	xp->y= COORDtoGRID( xfac, y0Ref+ sv->y )- lc->lcOy;
115 	}
116 
117     if  ( sd->sdVertexCount > 0 && xpret )
118 	{ xpret[sd->sdVertexCount]= xpret[0]; }
119 
120     return xpret;
121     }
122 
tedShapeGetLine(int * pLine,int * pWidthPixels,int * pWidthTwips,const DrawingShape * ds,DrawingContext * dc,ScreenDrawingData * sdd)123 static void tedShapeGetLine(	int *				pLine,
124 				int *				pWidthPixels,
125 				int *				pWidthTwips,
126 				const DrawingShape *		ds,
127 				DrawingContext *		dc,
128 				ScreenDrawingData *		sdd )
129     {
130     const ShapeDrawing *	sd= &(ds->dsDrawing);
131     RGB8Color			rgb8Stroke;
132 
133     docDrawShapeGetLine( pLine, &rgb8Stroke, ds, dc, sdd );
134 
135     if  ( *pLine )
136 	{
137 	const LayoutContext *	lc= &(dc->dcLayoutContext);
138 	int			widthTwips= EMUtoTWIPS( sd->sdLineWidthEmu );
139 	int			widthPixels= docLayoutXPixels( lc, widthTwips );
140 
141 	static unsigned char	dash[]= { 3, 2 };
142 	static unsigned char	dot[]= { 1, 2 };
143 	static unsigned char	dashdot[]= { 2, 2, 1, 2 };
144 	static unsigned char	dashdotdot[]= { 2, 2, 1, 2, 1, 2 };
145 
146 	const unsigned char *	dashList= (const unsigned char *)0;
147 	int			dashCount= 0;
148 	int			lineStyle= LineStyleSolid;
149 	int			capStyle= LineCapButt;
150 	int			joinStyle= LineJoinMiter;
151 
152 	if  ( widthPixels < 1 )
153 	    { widthPixels=  1;	}
154 
155 	switch( sd->sdLineDashing )
156 	    {
157 	    case DSdashSOLID:
158 		dashList= (const unsigned char *)0;
159 		dashCount= 0;
160 		lineStyle= LineStyleSolid;
161 		capStyle= LineCapButt;
162 		joinStyle= LineJoinMiter;
163 		break;
164 
165 	    case DSdashDASHED:
166 	    case DSdashDASHED_X:
167 	    case DSdashDASHED_L:
168 		dashList= dash;
169 		dashCount= sizeof( dash );
170 		lineStyle= LineStyleSingleDash;
171 		capStyle= LineCapButt;
172 		joinStyle= LineJoinMiter;
173 		break;
174 
175 	    case DSdashDOT:
176 	    case DSdashDOT_X:
177 		dashList= dot;
178 		dashCount= sizeof( dot );
179 		lineStyle= LineStyleSingleDash;
180 		capStyle= LineCapButt;
181 		joinStyle= LineJoinMiter;
182 		break;
183 
184 	    case DSdashDASHDOT:
185 	    case DSdashDASHDOT_X:
186 	    case DSdashDASHDOT_L:
187 		dashList= dashdot;
188 		dashCount= sizeof( dashdot );
189 		lineStyle= LineStyleSingleDash;
190 		capStyle= LineCapButt;
191 		joinStyle= LineJoinMiter;
192 		break;
193 
194 	    case DSdashDASHDOTDOT:
195 	    case DSdashDASHDOTDOT_L:
196 		dashList= dashdotdot;
197 		dashCount= sizeof( dashdotdot );
198 		lineStyle= LineStyleSingleDash;
199 		capStyle= LineCapButt;
200 		joinStyle= LineJoinMiter;
201 		break;
202 
203 	    default:
204 		LDEB(sd->sdLineDashing);
205 		dashList= (const unsigned char *)0;
206 		dashCount= 0;
207 	    }
208 
209 	drawSetLineAttributes( lc->lcDrawingSurface,
210 		    widthPixels, lineStyle, capStyle, joinStyle,
211 		    dashList, dashCount );
212 
213 	if  ( pWidthPixels )
214 	    { *pWidthPixels= widthPixels;	}
215 	if  ( pWidthTwips )
216 	    { *pWidthTwips= widthTwips;		}
217 	}
218     }
219 
tedShapeDrawPoints(const DrawingShape * ds,Point2DI * xp,int np,int closed,DrawingContext * dc,ScreenDrawingData * sdd)220 static int tedShapeDrawPoints(	const DrawingShape *		ds,
221 				Point2DI *			xp,
222 				int				np,
223 				int				closed,
224 				DrawingContext *		dc,
225 				ScreenDrawingData *		sdd )
226     {
227     const ShapeDrawing *	sd= &(ds->dsDrawing);
228     const LayoutContext *	lc= &(dc->dcLayoutContext);
229     double			xfac= lc->lcPixelsPerTwip;
230 
231     int				line= 0;
232     int				widthPixels;
233     int				widthTwips;
234 
235     int				drawStartArrow= 0;
236     DrawShapeArrow		dsaStart;
237     Point2DD			shaftStart[2];
238     int				drawEndArrow= 0;
239     DrawShapeArrow		dsaEnd;
240     Point2DD			shaftEnd[2];
241 
242     tedShapeGetLine( &line, &widthPixels, &widthTwips, ds, dc, sdd );
243 
244     if  ( line && ! closed && np >= 2 )
245 	{
246 	if  ( sd->sdLineHeadArrow.saArrowHead != DSarrowNONE )
247 	    {
248 	    drawStartArrow= 1;
249 
250 	    shaftStart[0].x= xp[1].x;
251 	    shaftStart[0].y= xp[1].y;
252 	    shaftStart[1].x= xp[0].x;
253 	    shaftStart[1].y= xp[0].y;
254 
255 	    docShapeArrowSizesTwips( &dsaStart, widthTwips, xfac,
256 					shaftStart, &(sd->sdLineHeadArrow) );
257 	    }
258 
259 	if  ( sd->sdLineTailArrow.saArrowHead != DSarrowNONE )
260 	    {
261 	    drawEndArrow= 1;
262 
263 	    shaftEnd[0].x= xp[np-2].x;
264 	    shaftEnd[0].y= xp[np-2].y;
265 	    shaftEnd[1].x= xp[np-1].x;
266 	    shaftEnd[1].y= xp[np-1].y;
267 
268 	    docShapeArrowSizesTwips( &dsaEnd, widthTwips, xfac,
269 					shaftEnd, &(sd->sdLineTailArrow) );
270 	    }
271 	}
272 
273     if  ( closed )
274 	{
275 	int		fill= 0;
276 	RGB8Color	rgb8Fill;
277 
278 	docDrawShapeGetFill( &fill, &rgb8Fill, ds, dc, sdd );
279 	if  ( fill )
280 	    { drawFillPolygon( lc->lcDrawingSurface, xp, np ); }
281 	}
282 
283     if  ( line )
284 	{
285 	if  ( drawStartArrow )
286 	    {
287 	    xp[0].x= dsaStart.dsaShaft[1].x;
288 	    xp[0].y= dsaStart.dsaShaft[1].y;
289 	    }
290 
291 	if  ( drawEndArrow )
292 	    {
293 	    xp[np-1].x= dsaEnd.dsaShaft[1].x;
294 	    xp[np-1].y= dsaEnd.dsaShaft[1].y;
295 	    }
296 
297 	drawLines( lc->lcDrawingSurface, xp, np, closed );
298 	}
299 
300     if  ( drawStartArrow )
301 	{ tedShapeDrawArrowHead( lc, widthPixels, &dsaStart );	}
302     if  ( drawEndArrow )
303 	{ tedShapeDrawArrowHead( lc, widthPixels, &dsaEnd );	}
304 
305     return 0;
306     }
307 
tedDrawSetShapePath(Point2DI * xp,const DrawingShape * ds,const ShapePath * sp,const DocumentRectangle * dr)308 static void tedDrawSetShapePath(Point2DI *			xp,
309 				const DrawingShape *		ds,
310 				const ShapePath *		sp,
311 				const DocumentRectangle *	dr )
312     {
313     const ShapeDrawing *	sd= &(ds->dsDrawing);
314     int				np= sp->spVertexCount;
315     const Point2DI *		sv= sp->spVertices;
316     int				i;
317 
318     if  ( sd->sdRotation == 0 )
319 	{
320 	int			xs= sp->spXSize;
321 	int			ys= sp->spYSize;
322 
323 	int			x0= dr->drX0;
324 	int			x1= dr->drX1;
325 	int			y0= dr->drY0;
326 	int			y1= dr->drY1;
327 
328 	if  ( DSflipHORIZONTAL( ds ) )
329 	    { int swap= x0; x0= x1; x1= swap;	}
330 	if  ( DSflipVERTICAL( ds ) )
331 	    { int swap= y0; y0= y1; y1= swap;	}
332 
333 	for ( i= 0; i < np; sv++, i++ )
334 	    {
335 	    xp[i].x= ( ( xs- sv->x )* x0+ sv->x* x1 )/ xs;
336 	    xp[i].y= ( ( ys- sv->y )* y0+ sv->y* y1 )/ ys;
337 	    }
338 	}
339     else{
340 	AffineTransform2D	at;
341 	double			xs= sp->spXSize;
342 	double			ys= sp->spYSize;
343 	double			xm= ( dr->drX1+ dr->drX0 )/ 2.0;
344 	double			ym= ( dr->drY1+ dr->drY0 )/ 2.0;
345 
346 	docShapeInternalTransform( &at, ds );
347 
348 	for ( i= 0; i < np; sv++, i++ )
349 	    {
350 	    double	x;
351 	    double	y;
352 
353 	    x= ( ( xs- sv->x )* dr->drX0+ sv->x* dr->drX1 )/ xs -xm;
354 	    y= ( ( ys- sv->y )* dr->drY0+ sv->y* dr->drY1 )/ ys- ym;
355 
356 	    xp[i].x= AT2_X( x, y, &at )+ xm;
357 	    xp[i].y= AT2_Y( x, y, &at )+ ym;
358 	    }
359 	}
360 
361     xp[np]= xp[0];
362 
363     return;
364     }
365 
tedDrawShapePath(const DrawingShape * ds,DrawingContext * dc,ScreenDrawingData * sdd,const DocumentRectangle * drPixels,const ShapePath * sp)366 static int tedDrawShapePath(	const DrawingShape *		ds,
367 				DrawingContext *		dc,
368 				ScreenDrawingData *		sdd,
369 				const DocumentRectangle *	drPixels,
370 				const ShapePath *		sp )
371     {
372     int			rval= 0;
373     int			np= sp->spVertexCount;
374     Point2DI *		xp;
375 
376     xp= malloc( ( np+ 1 )* sizeof(Point2DI) );
377     if  ( ! xp )
378 	{ LXDEB(np,xp); return -1;	}
379 
380     tedDrawSetShapePath( xp, ds, sp, drPixels );
381 
382     if  ( tedShapeDrawPoints( ds, xp, np, sp->spClosed, dc, sdd ) )
383 	{ LDEB(np); rval= -1;	}
384 
385     free( xp );
386 
387     return rval;
388     }
389 
tedDrawPictureFrame(DrawingShape * ds,DrawingContext * dc,ScreenDrawingData * sdd,const DocumentRectangle * drPixels)390 static int tedDrawPictureFrame( DrawingShape *			ds,
391 				DrawingContext *		dc,
392 				ScreenDrawingData *		sdd,
393 				const DocumentRectangle *	drPixels )
394     {
395     const LayoutContext *	lc= &(dc->dcLayoutContext);
396 
397     const ShapePath *		sp= &SP_RECTANGLE;
398     int				np= sp->spVertexCount;
399     Point2DI *			xp;
400 
401     int				fill= 0;
402     int				line= 0;
403     int				widthPixels= 0;
404 
405     RGB8Color			rgb8Fill;
406     DocumentRectangle		drSrc;
407 
408     xp= malloc( ( np+ 1 )* sizeof(Point2DI) );
409     if  ( ! xp )
410 	{ LXDEB(np,xp); return -1;	}
411 
412     tedDrawSetShapePath( xp, ds, sp, drPixels );
413 
414     docDrawShapeGetFill( &fill, &rgb8Fill, ds, dc, sdd );
415     if  ( fill )
416 	{ drawFillPolygon( lc->lcDrawingSurface, xp, np ); }
417 
418     drSrc= *drPixels;
419     geoShiftRectangle( &drSrc, -drPixels->drX0, -drPixels->drY0 );
420 
421     drawChildSurface( lc->lcDrawingSurface, ds->dsDrawingSurface,
422 					    drPixels->drX0, drPixels->drY0,
423 					    &drSrc );
424 
425     tedShapeGetLine( &line, &widthPixels, (int *)0, ds, dc, sdd );
426     if  ( line )
427 	{ drawLines( lc->lcDrawingSurface, xp, np+ 1, 0 ); }
428 
429     free( xp );
430 
431     return 0;
432     }
433 
tedDrawOnlineStorage(DrawingShape * ds,DrawingContext * dc,ScreenDrawingData * sdd,const DocumentRectangle * drPixels)434 static int tedDrawOnlineStorage( DrawingShape *			ds,
435 				DrawingContext *		dc,
436 				ScreenDrawingData *		sdd,
437 				const DocumentRectangle *	drPixels )
438     {
439     const LayoutContext *	lc= &(dc->dcLayoutContext);
440     DrawingSurface		drsf= lc->lcDrawingSurface;
441 
442     const ShapePath *		sp= &SP_RECTANGLE;
443     int				np= sp->spVertexCount;
444     Point2DI *			xp;
445     Arc2DI			arc;
446 
447     int				fill= 0;
448     int				line= 0;
449     int				widthPixels= 0;
450 
451     int				wide;
452     int				rx0;
453     int				rx1;
454 
455     RGB8Color			rgb8Fill;
456 
457     xp= malloc( ( np+ 1 )* sizeof(Point2DI) );
458     if  ( ! xp )
459 	{ LXDEB(np,xp); return -1;	}
460 
461     tedDrawSetShapePath( xp, ds, sp, drPixels );
462 
463     wide= drPixels->drX1- drPixels->drX0;
464     /*
465     high= drPixels->drY1- drPixels->drY0;
466     */
467     rx0= ( 5* drPixels->drX0+ 1* drPixels->drX1 )/ 6;
468     rx1= ( 1* drPixels->drX0+ 5* drPixels->drX1 )/ 6;
469 
470     arc.a2diRect= *drPixels;
471     arc.a2diRect.drX1= drPixels->drX0+ ( wide+ 2 )/ 3;
472     arc.a2diAngleFrom= 64* 90;
473     arc.a2diAngleStep= 64* 180;
474 
475     docDrawShapeGetFill( &fill, &rgb8Fill, ds, dc, sdd );
476     if  ( fill )
477 	{
478 	DocumentRectangle	drFill= *drPixels;
479 
480 	drawFillArc( drsf, &arc );
481 
482 	drFill.drX0= rx0;
483 	drFill.drX1= rx1;
484 	drawFillRectangle( drsf, &drFill );
485 	}
486 
487     tedShapeGetLine( &line, &widthPixels, (int *)0, ds, dc, sdd );
488     if  ( line )
489 	{
490 	drawArc( drsf, &arc );
491 
492 	drawLine( drsf, rx0, drPixels->drY0, rx1, drPixels->drY0 );
493 	drawLine( drsf, rx0, drPixels->drY1, rx1, drPixels->drY1 );
494 
495 	drawArc( drsf, &arc );
496 	}
497 
498     free( xp );
499 
500     return 0;
501     }
502 
tedDrawCan(DrawingShape * ds,DrawingContext * dc,ScreenDrawingData * sdd,const DocumentRectangle * drPixels)503 static int tedDrawCan( 		DrawingShape *			ds,
504 				DrawingContext *		dc,
505 				ScreenDrawingData *		sdd,
506 				const DocumentRectangle *	drPixels )
507     {
508     const LayoutContext *	lc= &(dc->dcLayoutContext);
509     DrawingSurface		drsf= lc->lcDrawingSurface;
510 
511     Arc2DI			topArc;
512     Arc2DI			botArc;
513 
514     int				fill= 0;
515     int				line= 0;
516     int				widthPixels= 0;
517 
518     int				ry0;
519     int				ry1;
520 
521     RGB8Color			rgb8Fill;
522 
523     ry0= ( 5* drPixels->drY0+ 1* drPixels->drY1 )/ 6;
524     ry1= ( 1* drPixels->drY0+ 5* drPixels->drY1 )/ 6;
525 
526     topArc.a2diRect= *drPixels;
527     topArc.a2diRect.drY0= drPixels->drY0;
528     topArc.a2diRect.drY1= ( 2* drPixels->drY0+ 1* drPixels->drY1 )/ 3;
529     topArc.a2diAngleFrom= 64* 0;
530     topArc.a2diAngleStep= 64* 360;
531 
532     botArc.a2diRect= *drPixels;
533     botArc.a2diRect.drY0= ( 1* drPixels->drY0+ 2* drPixels->drY1 )/ 3;
534     botArc.a2diRect.drY1= drPixels->drY1;
535     botArc.a2diAngleFrom= 64* 180;
536     botArc.a2diAngleStep= 64* 180;
537 
538     docDrawShapeGetFill( &fill, &rgb8Fill, ds, dc, sdd );
539     if  ( fill )
540 	{
541 	DocumentRectangle	drFill= *drPixels;
542 
543 	drawFillArc( drsf, &topArc );
544 
545 	drFill.drY0= ry0;
546 	drFill.drY1= ry1;
547 	drawFillRectangle( drsf, &drFill );
548 
549 	drawFillArc( drsf, &botArc );
550 	}
551 
552     tedShapeGetLine( &line, &widthPixels, (int *)0, ds, dc, sdd );
553     if  ( line )
554 	{
555 	drawArc( drsf, &topArc );
556 
557 	drawLine( drsf, drPixels->drX0, ry0, drPixels->drX0, ry1 );
558 	drawLine( drsf, drPixels->drX1, ry0, drPixels->drX1, ry1 );
559 
560 	drawArc( drsf, &botArc );
561 	}
562 
563     return 0;
564     }
565 
566 
tedDrawCallout(DrawingShape * ds,DrawingContext * dc,ScreenDrawingData * sdd,const DocumentRectangle * drPixels)567 static int tedDrawCallout(	DrawingShape *			ds,
568 				DrawingContext *		dc,
569 				ScreenDrawingData *		sdd,
570 				const DocumentRectangle *	drPixels )
571     {
572     const ShapeDrawing *	sd= &(ds->dsDrawing);
573     const LayoutContext *	lc= &(dc->dcLayoutContext);
574     DrawingSurface		drsf= lc->lcDrawingSurface;
575 
576     const ShapePath *	sp= &SP_RECTANGLE;
577     int			np= sp->spVertexCount;
578     Point2DI *		xp;
579 
580     int			fill= 0;
581     int			line= 0;
582     int			widthPixels= 0;
583 
584     RGB8Color		rgb8Fill;
585 
586     if  ( np != 4 )
587 	{ LDEB(np); return -1;	}
588 
589     xp= malloc( ( np+ 1+ 2+ 1 )* sizeof(Point2DI) );
590     if  ( ! xp )
591 	{ LXDEB(np,xp); return -1;	}
592 
593     tedDrawSetShapePath( xp, ds, sp, drPixels );
594 
595     docDrawShapeGetFill( &fill, &rgb8Fill, ds, dc, sdd );
596     if  ( fill )
597 	{ drawFillPolygon( drsf, xp, np ); }
598 
599     tedShapeGetLine( &line, &widthPixels, (int *)0, ds, dc, sdd );
600     if  ( line )
601 	{
602 	int		pp0= 5;
603 	int		pp1= pp0;
604 	long		a0, a2;
605 
606 	const int	SC= 21600; /* adjust to geoLeft etc? */
607 
608 	a2= sd->sdAdjustValue; a0= SC- a2;
609 	xp[pp1].x= ( a0* xp[0].x+ a2* xp[2].x )/ SC;
610 	a2= sd->sdAdjust2Value; a0= SC- a2;
611 	xp[pp1].y= ( a0* xp[0].y+ a2* xp[2].y )/ SC;
612 	pp1++;
613 
614 	a2= sd->sdAdjust3Value; a0= SC- a2;
615 	xp[pp1].x= ( a0* xp[0].x+ a2* xp[2].x )/ SC;
616 	a2= sd->sdAdjust4Value; a0= SC- a2;
617 	xp[pp1].y= ( a0* xp[0].y+ a2* xp[2].y )/ SC;
618 	pp1++;
619 
620 	drawLines( drsf, xp+ pp0, pp1- pp0, 0 );
621 	}
622 
623     free( xp );
624 
625     return 0;
626     }
627 
tedDrawDrawingShape(const DocumentRectangle * drTwips,int page,DrawingShape * ds,DrawingContext * dc,void * vsdd)628 int tedDrawDrawingShape(	const DocumentRectangle *	drTwips,
629 				int				page,
630 				DrawingShape *			ds,
631 				DrawingContext *		dc,
632 				void *				vsdd )
633     {
634     const ShapeDrawing *	sd= &(ds->dsDrawing);
635     const LayoutContext *	lc= &(dc->dcLayoutContext);
636     DrawingSurface		drsf= lc->lcDrawingSurface;
637     ScreenDrawingData *		sdd= (ScreenDrawingData *)vsdd;
638 
639     int				rval= 0;
640 
641     DocumentRectangle		drPixels;
642     DocumentRectangle		drNorm;
643     int				fill= 0;
644     int				line= 0;
645     int				widthPixels= 0;
646 
647     Point2DI *			xp= (Point2DI *)0;
648 
649     docGetPixelRect( &drPixels, lc, drTwips, page );
650     geoNormalizeRectangle( &drNorm, &drPixels );
651 
652     if  ( dc->dcClipRect						&&
653 	  ! geoIntersectRectangle( (DocumentRectangle *)0,
654 					    &drNorm, dc->dcClipRect )	)
655 	{ return 0;	}
656 
657     geoShiftRectangle( &drPixels, -lc->lcOx, -lc->lcOy );
658 
659     switch( sd->sdShapeType )
660 	{
661 	case SHPtyGROUP:
662 	    /* Done by docDrawDrawingShape(). */
663 	    LSDEB(sd->sdShapeType,docShapeTypeString(sd->sdShapeType));
664 	    break;
665 
666 	case 33:
667 	    if  ( tedDrawShapePath( ds, dc, sdd, &drPixels, &SP_33 ) )
668 		{ LDEB(1); rval= -1;	}
669 	    break;
670 
671 	case 34:
672 	    if  ( tedDrawShapePath( ds, dc, sdd, &drPixels, &SP_34 ) )
673 		{ LDEB(1); rval= -1;	}
674 	    break;
675 
676 	case SHPtyPICTURE_FRAME:
677 	    if  ( tedDrawPictureFrame( ds, dc, sdd, &drPixels ) )
678 		{ LDEB(1); rval= -1;	}
679 	    break;
680 
681 	case SHPtyCALLOUT_1:
682 	case SHPtyCALLOUT_90:
683 	    if  ( tedDrawCallout( ds, dc, sdd, &drPixels ) )
684 		{ LDEB(1); rval= -1;	}
685 	    break;
686 
687 	case SHPtyRECTANGLE:
688 	case SHPtyFLOW_CHART_PROCESS:
689 	case SHPtyACCENT_BORDER_CALLOUT_90:
690 	case SHPtyTEXT_BOX:
691 	    if  ( tedDrawShapePath( ds, dc, sdd, &drPixels, &SP_RECTANGLE ) )
692 		{ LDEB(1); rval= -1;	}
693 	    break;
694 
695 	case SHPtyROUND_RECTANGLE:
696 	case SHPtyFLOW_CHART_ALTERNATE_PROCESS:
697 	    {
698 	    RGB8Color		rgb8Fill;
699 
700 	    const int	w= ( drPixels.drX1- drPixels.drX0 )/ 4;
701 	    const int	h= ( drPixels.drY1- drPixels.drY0 )/ 4;
702 
703 	    docDrawShapeGetFill( &fill, &rgb8Fill, ds, dc, sdd );
704 	    if  ( fill )
705 		{ drawFillRoundedRect( drsf, &drPixels, w, h );	}
706 	    tedShapeGetLine( &line, &widthPixels, (int *)0, ds, dc, sdd );
707 	    if  ( line )
708 		{ drawRoundedRect( drsf, &drPixels, w, h );	}
709 	    }
710 	    break;
711 
712 	case SHPtyELLIPSE:
713 	case SHPtyFLOW_CHART_CONNECTOR:
714 	    {
715 	    RGB8Color		rgb8Fill;
716 	    Arc2DI		arc;
717 
718 	    arc.a2diRect= drPixels;
719 	    arc.a2diAngleFrom= 64* 0;
720 	    arc.a2diAngleStep= 64* 360;
721 
722 	    docDrawShapeGetFill( &fill, &rgb8Fill, ds, dc, sdd );
723 	    if  ( fill )
724 		{ drawFillArc( drsf, &arc );	}
725 
726 	    tedShapeGetLine( &line, &widthPixels, (int *)0, ds, dc, sdd );
727 	    if  ( line )
728 		{ drawArc( drsf, &arc );	}
729 	    }
730 	    break;
731 
732 	case SHPtyARC:
733 	    {
734 	    RGB8Color		rgb8Fill;
735 	    Arc2DI		arc;
736 
737 	    arc.a2diRect= drPixels;
738 	    arc.a2diAngleFrom= 64* 0;
739 	    arc.a2diAngleStep= 64* 90;
740 
741 	    docDrawShapeGetFill( &fill, &rgb8Fill, ds, dc, sdd );
742 	    if  ( fill )
743 		{ drawFillArc( drsf, &arc );	}
744 
745 	    tedShapeGetLine( &line, &widthPixels, (int *)0, ds, dc, sdd );
746 	    if  ( line )
747 		{ drawArc( drsf, &arc );	}
748 	    }
749 	    break;
750 
751 	case SHPtyDIAMOND:
752 	case SHPtyFLOW_CHART_DECISION:
753 	    if  ( tedDrawShapePath( ds, dc, sdd, &drPixels, &SP_DIAMOND ) )
754 		{ LDEB(1); rval= -1;	}
755 	    break;
756 
757 	case SHPtyISOSCELES_TRIANGLE:
758 	case SHPtyFLOW_CHART_EXTRACT:
759 	    if  ( tedDrawShapePath( ds, dc, sdd, &drPixels,
760 						    &SP_ISOSCELES_TRIANGLE ) )
761 		{ LDEB(1); rval= -1;	}
762 	    break;
763 
764 	case SHPtyFLOW_CHART_MERGE:
765 	    if  ( tedDrawShapePath( ds, dc, sdd, &drPixels,
766 						    &SP_FLOW_CHART_MERGE ) )
767 		{ LDEB(1); rval= -1;	}
768 	    break;
769 
770 	case SHPtyRIGHT_TRIANGLE:
771 	    if  ( tedDrawShapePath( ds, dc, sdd, &drPixels,
772 						    &SP_RIGHT_TRIANGLE ) )
773 		{ LDEB(1); rval= -1;	}
774 	    break;
775 
776 	case SHPtyPARALLELOGRAM:
777 	case SHPtyFLOW_CHART_INPUT_OUTPUT:
778 	    if  ( tedDrawShapePath( ds, dc, sdd, &drPixels,
779 						    &SP_PARALLELOGRAM ) )
780 		{ LDEB(1); rval= -1;	}
781 	    break;
782 
783 	case SHPtyTRAPEZOID:
784 	case SHPtyFLOW_CHART_MANUAL_OPERATION:
785 	    if  ( tedDrawShapePath( ds, dc, sdd, &drPixels, &SP_TRAPEZOID ) )
786 		{ LDEB(1); rval= -1;	}
787 	    break;
788 
789 	case SHPtyHEXAGON:
790 	case SHPtyFLOW_CHART_PREPARATION:
791 	    if  ( tedDrawShapePath( ds, dc, sdd, &drPixels, &SP_HEXAGON ) )
792 		{ LDEB(1); rval= -1;	}
793 	    break;
794 
795 	case SHPtyOCTAGON:
796 	    if  ( tedDrawShapePath( ds, dc, sdd, &drPixels, &SP_OCTAGON ) )
797 		{ LDEB(1); rval= -1;	}
798 	    break;
799 
800 	case SHPtyPLUS_SIGN:
801 	    if  ( tedDrawShapePath( ds, dc, sdd, &drPixels, &SP_PLUS_SIGN ) )
802 		{ LDEB(1); rval= -1;	}
803 	    break;
804 
805 	case SHPtyARROW:
806 	    if  ( tedDrawShapePath( ds, dc, sdd, &drPixels, &SP_ARROW ) )
807 		{ LDEB(1); rval= -1;	}
808 	    break;
809 
810 	case SHPtyNOTCHED_RIGHT_ARROW:
811 	    if  ( tedDrawShapePath( ds, dc, sdd, &drPixels, &SP_NOTCHED_RIGHT_ARROW ) )
812 		{ LDEB(1); rval= -1;	}
813 	    break;
814 
815 	case SHPtyHOME_PLATE:
816 	    if  ( tedDrawShapePath( ds, dc, sdd, &drPixels, &SP_HOME_PLATE ) )
817 		{ LDEB(1); rval= -1;	}
818 	    break;
819 
820 	case SHPtyCHEVRON:
821 	    if  ( tedDrawShapePath( ds, dc, sdd, &drPixels, &SP_CHEVRON ) )
822 		{ LDEB(1); rval= -1;	}
823 	    break;
824 
825 	case SHPtyLEFT_ARROW:
826 	    if  ( tedDrawShapePath( ds, dc, sdd, &drPixels, &SP_LEFT_ARROW ) )
827 		{ LDEB(1); rval= -1;	}
828 	    break;
829 
830 	case SHPtyRIGHT_ARROW_CALLOUT:
831 	    if  ( tedDrawShapePath( ds, dc, sdd, &drPixels, &SP_RIGHT_ARROW_CALLOUT ) )
832 		{ LDEB(1); rval= -1;	}
833 	    break;
834 	case SHPtyLEFT_ARROW_CALLOUT:
835 	    if  ( tedDrawShapePath( ds, dc, sdd, &drPixels, &SP_LEFT_ARROW_CALLOUT ) )
836 		{ LDEB(1); rval= -1;	}
837 	    break;
838 	case SHPtyUP_ARROW_CALLOUT:
839 	    if  ( tedDrawShapePath( ds, dc, sdd, &drPixels, &SP_UP_ARROW_CALLOUT ) )
840 		{ LDEB(1); rval= -1;	}
841 	    break;
842 	case SHPtyDOWN_ARROW_CALLOUT:
843 	    if  ( tedDrawShapePath( ds, dc, sdd, &drPixels, &SP_DOWN_ARROW_CALLOUT ) )
844 		{ LDEB(1); rval= -1;	}
845 	    break;
846 
847 	case SHPtyLEFT_RIGHT_ARROW_CALLOUT:
848 	    if  ( tedDrawShapePath( ds, dc, sdd, &drPixels, &SP_LEFT_RIGHT_ARROW_CALLOUT ) )
849 		{ LDEB(1); rval= -1;	}
850 	    break;
851 
852 	case SHPtyUP_DOWN_ARROW_CALLOUT:
853 	    if  ( tedDrawShapePath( ds, dc, sdd, &drPixels, &SP_UP_DOWN_ARROW_CALLOUT ) )
854 		{ LDEB(1); rval= -1;	}
855 	    break;
856 
857 	case SHPtyQUAD_ARROW_CALLOUT:
858 	    if  ( tedDrawShapePath( ds, dc, sdd, &drPixels, &SP_QUAD_ARROW_CALLOUT ) )
859 		{ LDEB(1); rval= -1;	}
860 	    break;
861 
862 	case SHPtyLEFT_RIGHT_ARROW:
863 	    if  ( tedDrawShapePath( ds, dc, sdd, &drPixels, &SP_LEFT_RIGHT_ARROW ) )
864 		{ LDEB(1); rval= -1;	}
865 	    break;
866 
867 	case SHPtyUP_ARROW:
868 	    if  ( tedDrawShapePath( ds, dc, sdd, &drPixels, &SP_UP_ARROW ) )
869 		{ LDEB(1); rval= -1;	}
870 	    break;
871 
872 	case SHPtyDOWN_ARROW:
873 	    if  ( tedDrawShapePath( ds, dc, sdd, &drPixels, &SP_DOWN_ARROW ) )
874 		{ LDEB(1); rval= -1;	}
875 	    break;
876 
877 	case SHPtyUP_DOWN_ARROW:
878 	    if  ( tedDrawShapePath( ds, dc, sdd, &drPixels, &SP_UP_DOWN_ARROW ) )
879 		{ LDEB(1); rval= -1;	}
880 	    break;
881 
882 	case SHPtyQUAD_ARROW:
883 	    if  ( tedDrawShapePath( ds, dc, sdd, &drPixels, &SP_QUAD_ARROW ) )
884 		{ LDEB(1); rval= -1;	}
885 	    break;
886 
887 	case SHPtyLEFT_RIGHT_UP_ARROW:
888 	    if  ( tedDrawShapePath( ds, dc, sdd, &drPixels, &SP_LEFT_RIGHT_UP_ARROW ) )
889 		{ LDEB(1); rval= -1;	}
890 	    break;
891 
892 	case SHPtyLEFT_UP_ARROW:
893 	    if  ( tedDrawShapePath( ds, dc, sdd, &drPixels, &SP_LEFT_UP_ARROW ) )
894 		{ LDEB(1); rval= -1;	}
895 	    break;
896 
897 	case SHPtyBENT_UP_ARROW:
898 	    if  ( tedDrawShapePath( ds, dc, sdd, &drPixels, &SP_BENT_UP_ARROW ) )
899 		{ LDEB(1); rval= -1;	}
900 	    break;
901 
902 	case SHPtyPENTAGON:
903 	    if  ( tedDrawShapePath( ds, dc, sdd, &drPixels, &SP_PENTAGON ) )
904 		{ LDEB(1); rval= -1;	}
905 	    break;
906 
907 	case SHPtySTAR:
908 	    if  ( tedDrawShapePath( ds, dc, sdd, &drPixels, &SP_STAR ) )
909 		{ LDEB(1); rval= -1;	}
910 	    break;
911 
912 	case SHPtySEAL4:
913 	    if  ( tedDrawShapePath( ds, dc, sdd, &drPixels, &SP_SEAL4 ) )
914 		{ LDEB(1); rval= -1;	}
915 	    break;
916 
917 	case 32:
918 	case SHPtyLINE:
919 	    if  ( tedDrawShapePath( ds, dc, sdd, &drPixels, &SP_LINE ) )
920 		{ LDEB(1); rval= -1;	}
921 	    break;
922 
923 	case SHPtyFLOW_CHART_MANUAL_INPUT:
924 	    if  ( tedDrawShapePath( ds, dc, sdd, &drPixels, &SP_FLOW_CHART_MANUAL_INPUT ) )
925 		{ LDEB(1); rval= -1;	}
926 	    break;
927 	case SHPtyFLOW_CHART_OFF_PAGE_CONNECTOR:
928 	    if  ( tedDrawShapePath( ds, dc, sdd, &drPixels, &SP_FLOW_CHART_OFF_PAGE_CONNECTOR ) )
929 		{ LDEB(1); rval= -1;	}
930 	    break;
931 
932 	case SHPtyFLOW_CHART_PUNCHED_CARD:
933 	    if  ( tedDrawShapePath( ds, dc, sdd, &drPixels, &SP_FLOW_CHART_PUNCHED_CARD ) )
934 		{ LDEB(1); rval= -1;	}
935 	    break;
936 
937 	case SHPtyWEDGE_RECT_CALLOUT:
938 	    if  ( tedDrawShapePath( ds, dc, sdd, &drPixels, &SP_WEDGE_RECT_CALLOUT ) )
939 		{ LDEB(1); rval= -1;	}
940 	    break;
941 
942 	case SHPtyFLOW_CHART_ONLINE_STORAGE:
943 	    if  ( tedDrawOnlineStorage( ds, dc, sdd, &drPixels ) )
944 		{ LDEB(1); rval= -1;	}
945 	    break;
946 
947 	case SHPtyCAN:
948 	case SHPtyFLOW_CHART_MAGNETIC_DISK:
949 	    if  ( tedDrawCan( ds, dc, sdd, &drPixels ) )
950 		{ LDEB(1); rval= -1;	}
951 	    break;
952 
953 	case SHPtyRIGHT_BRACE:
954 	    {
955 	    const ShapePath *	sp= &SP_RECTANGLE;
956 	    int			np= sp->spVertexCount;
957 	    Point2DI *		xp;
958 
959 	    int			wide;
960 
961 	    xp= malloc( ( np+ 1 )* sizeof(Point2DI) );
962 	    if  ( ! xp )
963 		{ LXDEB(np,xp); return -1;	}
964 
965 	    tedDrawSetShapePath( xp, ds, sp, &drPixels );
966 
967 	    wide= xp[2].x- xp[0].x;
968 	    /*
969 	    high= xp[2].y- xp[0].y;
970 	    */
971 
972 	    tedShapeGetLine( &line, &widthPixels, (int *)0, ds, dc, sdd );
973 
974 # if 0
975 	    appDrawDrawArc( add, xp[0].x- wide/ 2,
976 				    ( 8* xp[0].y+ 0* xp[2].y )/ 8,
977 				    wide+ 1, ( high+ 3 )/ 4,
978 				    64* 0, 64* 90 );
979 # endif
980 
981 	    drawLine( drsf,
982 		    xp[0].x+ wide/ 2, ( 7* xp[0].y+ 1* xp[2].y )/ 8,
983 		    xp[0].x+ wide/ 2, ( 5* xp[0].y+ 3* xp[2].y )/ 8 );
984 
985 # if 0
986 	    appDrawDrawArc( add, xp[2].x- wide/ 2,
987 				    ( 6* xp[0].y+ 2* xp[2].y )/ 8,
988 				    wide+ 1, ( high+ 3 )/ 4,
989 				    64* 180, 64* 90 );
990 
991 	    appDrawDrawArc( add, xp[2].x- wide/ 2,
992 				    ( 4* xp[0].y+ 4* xp[2].y )/ 8,
993 				    wide+ 1, ( high+ 3 )/ 4,
994 				    64* 90, 64* 90 );
995 # endif
996 
997 	    drawLine( drsf,
998 		    xp[0].x+ wide/ 2, ( 3* xp[0].y+ 5* xp[2].y )/ 8,
999 		    xp[0].x+ wide/ 2, ( 1* xp[0].y+ 7* xp[2].y )/ 8 );
1000 
1001 # if 0
1002 	    appDrawDrawArc( add, xp[0].x- wide/ 2,
1003 				    ( 2* xp[0].y+ 6* xp[2].y )/ 8,
1004 				    wide+ 1, ( high+ 3 )/ 4,
1005 				    64* 270, 64* 90 );
1006 # endif
1007 
1008 	    free( xp );
1009 	    }
1010 	    break;
1011 
1012 	case SHPtyFREEFORM_OR_NON_AUTOSHAPE:
1013 	    if  ( sd->sdVertexCount > 1 )
1014 		{
1015 		const int	closed= 1;
1016 
1017 		xp= tedDrawGetVertices( drTwips, ds, lc, sdd );
1018 		if  ( ! xp )
1019 		    { XDEB(xp); rval= -1; goto ready;	}
1020 
1021 		tedShapeDrawPoints( ds, xp, sd->sdVertexCount- 1,
1022 						    closed, dc, sdd );
1023 		}
1024 	    break;
1025 
1026 	case SHPtyBENT_ARROW:
1027 	default:
1028 	    LSDEB(sd->sdShapeType,docShapeTypeString(sd->sdShapeType));
1029 	    break;
1030 	}
1031 
1032     /* Done by docDrawDrawingShape()....
1033     if  ( ds->dsDocumentTree.dtRoot )
1034 	{}
1035     */
1036 
1037   ready:
1038     if  ( xp )
1039 	{ free( xp ); }
1040 
1041     return rval;
1042     }
1043 
1044