1 /************************************************************************/
2 /*									*/
3 /*  Read RTF shapes.							*/
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	"docRtfReaderImpl.h"
16 #   include	"docRtfTags.h"
17 #   include	"docRtfShpTab.h"
18 #   include	<docShape.h>
19 #   include	<docShapeProp.h>
20 #   include	<docObjectProperties.h>
21 #   include	<docTreeType.h>
22 #   include	<docNodeTree.h>
23 #   include	<docParaParticules.h>
24 
25 /************************************************************************/
26 
27 static int docRtfReadChildShape(	const RtfControlWord *	rcw,
28 					int			arg,
29 					RtfReader *		rr );
30 
31 /************************************************************************/
32 /*									*/
33 /*  Property control words inside a shape.				*/
34 /*									*/
35 /************************************************************************/
36 
docRtfShpProperty(const RtfControlWord * rcw,int arg,RtfReader * rr)37 int docRtfShpProperty(		const RtfControlWord *	rcw,
38 				int			arg,
39 				RtfReader *		rr )
40     {
41     DrawingShape *	ds= rr->rrDrawingShape;
42     ShapeProperties *	sp;
43 
44     if  ( ! ds )
45 	{ SLLXDEB(rcw->rcwWord,arg,rr->rrCurrentLine,ds); return 0;	}
46 
47     sp= &(ds->dsShapeProperties);
48 
49     if  ( rcw->rcwID != SHPpropLID	&&
50 	  ds->dsIsChildShape		)
51 	{ SLDEB(rcw->rcwWord,ds->dsIsChildShape);	}
52 
53     if  ( docSetShapeProperty( sp, rcw->rcwID, arg ) )
54 	{ SLDEB(rcw->rcwWord,arg);	}
55 
56     return 0;
57     }
58 
59 /************************************************************************/
60 /*									*/
61 /*  Content inside a shape.						*/
62 /*									*/
63 /************************************************************************/
64 
docRtfShpText(const RtfControlWord * rcw,int arg,RtfReader * rr)65 static int docRtfShpText(	const RtfControlWord *	rcw,
66 				int			arg,
67 				RtfReader *		rr )
68     {
69     DrawingShape *	ds= rr->rrDrawingShape;
70 
71     int			treeType= DOCinSHPTXT;
72     const int		ignoreEmpty= 0;
73 
74     /* No! to deal with faulty documents.
75     rr->rrDrawingShape= (DrawingShape *)0;
76     */
77 
78     if  ( docRtfReadDocumentTree( rcw, &(ds->dsDocumentTree), &treeType,
79 				rr, ignoreEmpty, &(ds->dsSelectionScope) ) )
80 	{ SDEB(rcw->rcwWord); return -1;	}
81 
82     if  ( ds->dsSelectionScope.ssTreeType != treeType )
83 	{
84 	LLDEB(ds->dsSelectionScope.ssTreeType,treeType);
85 	ds->dsSelectionScope.ssTreeType= treeType;
86 	docSetTreeTypeOfNode( ds->dsDocumentTree.dtRoot, treeType );
87 	}
88 
89     /* No! to deal with faulty documents.
90     rr->rrDrawingShape= ds;
91     */
92     return 0;
93     }
94 
95 /************************************************************************/
96 /*									*/
97 /*  Read an {\sn .... } {\sv .... } pair.				*/
98 /*									*/
99 /*  NOTE that the concept of an 'RtfControlWord' is abused for		*/
100 /*	 the shape property.						*/
101 /*									*/
102 /************************************************************************/
103 
docRtfShpCollectNumbers(int * numbers,int count,char * from)104 static int docRtfShpCollectNumbers(	int *			numbers,
105 					int			count,
106 					char *			from )
107     {
108     int		rval= 0;
109     int		i;
110 
111     for ( i= 0; i < count; i++ )
112 	{
113 	char *		past;
114 	long		val;
115 
116 	while( isspace( *from ) )
117 	    { from++;	}
118 	if  ( from[0] != ';' )
119 	    { SDEB(from); rval= -1; goto ready;	}
120 	from++;
121 	while( isspace( *from ) )
122 	    { from++;	}
123 
124 	past= from;
125 	val= strtol( from, &past, 10 );
126 	if  ( past == from )
127 	    { SDEB(from); rval= -1; goto ready;	}
128 	from= past;
129 
130 	numbers[i]= val;
131 	}
132 
133     if  ( count > 0 )
134 	{ numbers[count]= numbers[0]; }
135 
136   ready:
137 
138     return rval;
139     }
140 
docRtfShpCollectVertices(Point2DI * vertices,int count,char * from)141 static int docRtfShpCollectVertices(	Point2DI *		vertices,
142 					int			count,
143 					char *			from )
144     {
145     int			rval= 0;
146     int			i;
147 
148     for ( i= 0; i < count; i++ )
149 	{
150 	char *		past;
151 	long		val;
152 
153 	while( isspace( *from ) )
154 	    { from++;	}
155 	if  ( from[0] != ';' )
156 	    { SDEB(from); rval= -1; goto ready;	}
157 	from++;
158 	while( isspace( *from ) )
159 	    { from++;	}
160 	if  ( from[0] != '(' )
161 	    { SDEB(from); rval= -1; goto ready;	}
162 	from++;
163 	while( isspace( *from ) )
164 	    { from++;	}
165 
166 	past= from;
167 	val= strtol( from, &past, 10 );
168 	if  ( past == from )
169 	    { SDEB(from); rval= -1; goto ready;	}
170 	from= past;
171 	vertices[i].x= val;
172 
173 	while( isspace( *from ) )
174 	    { from++;	}
175 	if  ( from[0] != ',' )
176 	    { SDEB(from); rval= -1; goto ready;	}
177 	from++;
178 	while( isspace( *from ) )
179 	    { from++;	}
180 
181 	past= from;
182 	val= strtol( from, &past, 10 );
183 	if  ( past == from )
184 	    { SDEB(from); rval= -1; goto ready;	}
185 	from= past;
186 	vertices[i].y= val;
187 
188 	while( isspace( *from ) )
189 	    { from++;	}
190 	if  ( from[0] != ')' )
191 	    { SDEB(from); rval= -1; goto ready;	}
192 	from++;
193 	while( isspace( *from ) )
194 	    { from++;	}
195 	}
196 
197     if  ( count > 0 )
198 	{ vertices[count]= vertices[0]; }
199 
200 ready:
201 
202     return rval;
203     }
204 
docRtfShpArray(const RtfControlWord * rcw,int arg,RtfReader * rr)205 int docRtfShpArray(	const RtfControlWord *	rcw,
206 			int			arg,
207 			RtfReader *		rr )
208     {
209     int			rval= 0;
210 
211     DrawingShape *	ds= rr->rrDrawingShape;
212     ShapeDrawing *	sd;
213 
214     int			unitSize;
215     int			count;
216 
217     const int		removeSemicolon= 0;
218     char *		text= (char *)0;
219     char *		from;
220     char *		past;
221     int			size;
222 
223     long		val;
224 
225     Point2DI *		vertices= (Point2DI *)0;
226     int *		numbers= (int *)0;
227 
228     if  ( docRtfStoreSavedText( &text, &size, rr, removeSemicolon ) )
229 	{ LDEB(1); rval= -1; goto ready;	}
230 
231     from= text;
232     while( isspace( *from ) )
233 	{ from++;	}
234 
235     past= from;
236     val= strtol( from, &past, 10 );
237     if  ( past == from )
238 	{ SDEB(from); rval= -1; goto ready;	}
239     from= past;
240     unitSize= val;
241 
242     while( isspace( *from ) )
243 	{ from++;	}
244     if  ( *from != ';' )
245 	{ SDEB(from); rval= -1; goto ready;	}
246     from++;
247     while( isspace( *from ) )
248 	{ from++;	}
249 
250     past= from;
251     val= strtol( from, &past, 10 );
252     if  ( past == from )
253 	{ SDEB(from); rval= -1; goto ready;	}
254     from= past;
255     count= val;
256 
257     switch( unitSize )
258 	{
259 	case 8:
260 	    vertices= (Point2DI *)malloc( (count+ 1)* sizeof( Point2DI ) );
261 	    if  ( ! vertices )
262 		{ LXDEB(count,vertices); rval= -1; goto ready; }
263 	    if  ( docRtfShpCollectVertices( vertices, count, from ) )
264 		{ LDEB(count); rval= -1; goto ready;	}
265 	    break;
266 
267 	case 2:
268 	case 4:
269 	    numbers= (int *)malloc( (count+ 1)* sizeof( int ) );
270 	    if  ( ! numbers )
271 		{ LXDEB(count,numbers); rval= -1; goto ready; }
272 	    if  ( docRtfShpCollectNumbers( numbers, count, from ) )
273 
274 		{ LDEB(count); rval= -1; goto ready;	}
275 	    break;
276 
277 	default:
278 	    LLDEB(count,unitSize); rval= -1; goto ready;
279 	}
280 
281     if  ( ! ds )
282 	{ SXDEB(rcw->rcwWord,ds); goto ready;	}
283     sd= &(ds->dsDrawing);
284 
285     switch( rcw->rcwID )
286 	{
287 	case DSHPprop_pVerticies:
288 	    sd->sdVertices= vertices;
289 	    vertices= (Point2DI *)0;	/* steal */
290 	    sd->sdVertexCount= count;
291 	    break;
292 
293 	case DSHPprop_pWrapPolygonVertices:
294 	    sd->sdWrapPolygonVertices= vertices;
295 	    vertices= (Point2DI *)0;	/* steal */
296 	    sd->sdWrapPolygonVertexCount= count;
297 	    break;
298 
299 	case DSHPprop_pSegmentInfo:
300 	    sd->sdSegmentInfos= numbers;
301 	    numbers= (int *)0;	/* steal */
302 	    sd->sdSegmentInfoCount= count;
303 	    break;
304 
305 	default:
306 	    SDEB(rcw->rcwWord);
307 	    break;
308 	}
309 
310   ready:
311     if  ( text )
312 	{ free( text );	}
313     if  ( vertices )
314 	{ free( vertices );	}
315     if  ( numbers )
316 	{ free( numbers );	}
317 
318     return rval;
319     }
320 
321 /************************************************************************/
322 /*									*/
323 /*  Consume a picture value attached to a shape.			*/
324 /*									*/
325 /************************************************************************/
326 
docRtfSaveShapeData(RtfReader * rr,const char * text,int len)327 static int docRtfSaveShapeData(	RtfReader *	rr,
328 				const char *		text,
329 				int			len )
330     {
331     DrawingShape *	ds= rr->rrDrawingShape;
332 
333     if  ( ! ds )
334 	{ XDEB(ds); return 0;	}
335 
336     if  ( rr->rrcInIgnoredGroup > 0 )
337 	{ return 0;	}
338 
339     if  ( utilMemoryBufferSetBytes( &(ds->dsPictureData),
340 					(const unsigned char *)text, len ) )
341 	{ LDEB(len); return -1;	}
342 
343     return 0;
344     }
345 
346 
docRtfReadShapePicture(const RtfControlWord * rcw,int arg,RtfReader * rr)347 static int docRtfReadShapePicture(	const RtfControlWord *	rcw,
348 					int			arg,
349 					RtfReader *		rr )
350     {
351     RtfReadingState		internRrs;
352 
353     int				rval;
354 
355     docRtfPushReadingState( rr, &internRrs );
356 
357     utilPropMaskClear( &(rr->rrcPicturePropMask) );
358     docInitPictureProperties( &(rr->rrcPictureProperties) );
359 
360     rval= docRtfConsumeGroup( (const RtfControlWord *)0, 0, -1, rr,
361 			    (const RtfControlWord *)0, docRtfSaveShapeData );
362 
363     if  ( rval )
364 	{ SLDEB(rcw->rcwWord,rval);	}
365 
366     docRtfPopReadingState( rr );
367 
368     return rval;
369     }
370 
docRtfShpPicture(const RtfControlWord * rcw,int arg,RtfReader * rr)371 int docRtfShpPicture(	const RtfControlWord *	rcw,
372 			int			arg,
373 			RtfReader *		rr )
374     {
375     DrawingShape *	ds= rr->rrDrawingShape;
376 
377     if  ( ! ds )
378 	{ XDEB(ds);						}
379     else{ ds->dsPictureProperties= rr->rrcPictureProperties;	}
380 
381     return 0;
382     }
383 
docRtfShpString(const RtfControlWord * rcw,int arg,RtfReader * rr)384 int docRtfShpString(	const RtfControlWord *	rcw,
385 			int			arg,
386 			RtfReader *		rr )
387     {
388     const int	removeSemicolon= 0;
389     char *	text= (char *)0;
390     int		size;
391 
392     if  ( docRtfStoreSavedText( &text, &size, rr, removeSemicolon ) )
393 	{ LDEB(1); return -1;	}
394 
395     /*
396     SSDEB(rcw->rcwWord,text);
397     */
398 
399     if  ( text )
400 	{ free( text );	}
401 
402     return 0;
403     }
404 
docRtfShpGetNumber(long * pVal,RtfReader * rr)405 static int docRtfShpGetNumber(	long *			pVal,
406 				RtfReader *		rr )
407     {
408     int			rval= 0;
409     long		val;
410 
411     const int		removeSemicolon= 0;
412     char *		text= (char *)0;
413     char *		from;
414     char *		past;
415     int			size;
416 
417     if  ( docRtfStoreSavedText( &text, &size, rr, removeSemicolon ) )
418 	{ LDEB(1); rval= -1; goto ready;	}
419 
420     from= text;
421     while( isspace( *from ) )
422 	{ from++;	}
423     past= from;
424     val= strtol( from, &past, 10 );
425     if  ( past == from )
426 	{ SDEB(from); rval= -1; goto ready;	}
427     from= past;
428 
429     *pVal= val;
430 
431   ready:
432 
433     if  ( text )
434 	{ free( text );	}
435 
436     return rval;
437     }
438 
docRtfShapeNumber(const RtfControlWord * rcw,int arg,RtfReader * rr)439 int docRtfShapeNumber(		const RtfControlWord *	rcw,
440 				int			arg,
441 				RtfReader *		rr )
442     {
443     DrawingShape *	ds= rr->rrDrawingShape;
444     long		val;
445 
446     if  ( docRtfShpGetNumber( &val, rr ) )
447 	{ SDEB(rcw->rcwWord); return -1;	}
448 
449     if  ( ! ds )
450 	{ SXDEB(rcw->rcwWord,ds); return 0;	}
451 
452     if  ( docSetShapeDrawingProperty( &(ds->dsDrawing), rcw->rcwID, val ) )
453 	{ SLDEB(rcw->rcwWord,val);	}
454 
455     return 0;
456     }
457 
docRtfShpColor(const RtfControlWord * rcw,int arg,RtfReader * rr)458 int docRtfShpColor(	const RtfControlWord *	rcw,
459 			int			arg,
460 			RtfReader *		rr )
461     {
462     DrawingShape *	ds= rr->rrDrawingShape;
463     ShapeDrawing *	sd;
464     long		val;
465     RGB8Color		rgb8;
466 
467     if  ( docRtfShpGetNumber( &val, rr ) )
468 	{ SDEB(rcw->rcwWord); return -1;	}
469 
470     if  ( ! ds )
471 	{ SXDEB(rcw->rcwWord,ds); return 0;	}
472     sd= &(ds->dsDrawing);
473 
474     utilInitRGB8Color( &rgb8 );
475     rgb8.rgb8Red= val & 255; val /= 256;
476     rgb8.rgb8Green= val & 255; val /= 256;
477     rgb8.rgb8Blue= val & 255; val /= 256;
478 
479     switch( rcw->rcwID )
480 	{
481 	case DSHPprop_fillColor:
482 	    sd->sdFillColor= rgb8;
483 	    break;
484 	case DSHPprop_fillBackColor:
485 	    sd->sdFillBackColor= rgb8;
486 	    break;
487 	case DSHPprop_fillCrMod:
488 	    sd->sdFillCrModColor= rgb8;
489 	    break;
490 
491 	case DSHPprop_lineColor:
492 	    sd->sdLineColor= rgb8;
493 	    break;
494 	case DSHPprop_lineBackColor:
495 	    sd->sdLineBackColor= rgb8;
496 	    break;
497 	case DSHPprop_lineCrMod:
498 	    sd->sdLineCrModColor= rgb8;
499 	    break;
500 
501 	case DSHPprop_shadowColor:
502 	    sd->sdShadowColor= rgb8;
503 	    break;
504 	case DSHPprop_shadowHighlight:
505 	    sd->sdShadowHighlightColor= rgb8;
506 	    break;
507 	case DSHPprop_shadowCrMod:
508 	    sd->sdShadowCrModColor= rgb8;
509 	    break;
510 	case DSHPprop_c3DExtrusionColor:
511 	    sd->sdShadowc3DExtrusionColor= rgb8;
512 	    break;
513 	case DSHPprop_c3DCrMod:
514 	    sd->sdShadowc3DCrModColor= rgb8;
515 	    break;
516 
517 	case DSHPprop_pictureTransparent:
518 	    /* ? */
519 	    break;
520 
521 	default:
522 	    SDEB(rcw->rcwWord);
523 	    break;
524 	}
525 
526     return 0;
527     }
528 
docRtfShapeProperty(const RtfControlWord * rcw,int arg,RtfReader * rr)529 int docRtfShapeProperty(	const RtfControlWord *	rcw,
530 				int			arg,
531 				RtfReader *		rr )
532     {
533     int				rval= 0;
534 
535     if  ( rr->rrShapeProperty )
536 	{ SDEB(rr->rrShapeProperty->rcwWord);	}
537 
538     if  ( ! docRtfGetParaNode( rr ) )
539 	{ SDEB(rcw->rcwWord); return -1; }
540 
541     rr->rrShapeProperty= (struct RtfControlWord *)0;
542     utilEmptyMemoryBuffer( &(rr->rrShapePropertyName) );
543     utilEmptyMemoryBuffer( &(rr->rrShapePropertyValue) );
544 
545     if  ( docRtfReadGroup( rcw, 0, 0, rr,
546 		(RtfControlWord *)0, docRtfRefuseText, (RtfCommitGroup)0 ) )
547 	{ SDEB(rcw->rcwWord); rval= -1;	}
548 
549     rr->rrShapeProperty= (struct RtfControlWord *)0;
550     utilEmptyMemoryBuffer( &(rr->rrShapePropertyName) );
551     utilEmptyMemoryBuffer( &(rr->rrShapePropertyValue) );
552 
553     return rval;
554     }
555 
docRtfCommitShapePropertyName(const RtfControlWord * rcw,RtfReader * rr)556 static int docRtfCommitShapePropertyName(
557 					const RtfControlWord *	rcw,
558 					RtfReader *		rr )
559     {
560     const int	removeSemicolon= 0;
561     char *	text= (char *)0;
562     int		size;
563 
564     if  ( docRtfStoreSavedText( &text, &size, rr, removeSemicolon ) )
565 	{ LDEB(1); return -1;	}
566 
567     if  ( text )
568 	{
569 	rr->rrShapeProperty= docRtfFindShapePropertyWord( text );
570 	if  ( ! rr->rrShapeProperty )
571 	    { SXDEB(text,rr->rrShapeProperty);	}
572 
573 	free( text );
574 	}
575     else{ XDEB(text);		}
576 
577     return 0;
578     }
579 
docRtfCommitShapePropertyValue(const RtfControlWord * rcw,RtfReader * rr)580 static int docRtfCommitShapePropertyValue(
581 					const RtfControlWord *	rcw,
582 					RtfReader *		rr )
583     {
584     if  ( rr->rrShapeProperty )
585 	{
586 	if  ( (*rr->rrShapeProperty->rcwApply)( rr->rrShapeProperty, 0, rr ) )
587 	    {  SDEB(rr->rrShapeProperty->rcwWord); return -1;	}
588 	}
589     else{
590 	const int	removeSemicolon= 0;
591 	char *		text= (char *)0;
592 	int		size;
593 
594 	if  ( docRtfStoreSavedText( &text, &size, rr, removeSemicolon ) )
595 	    { LDEB(1); return -1;	}
596 
597 	if  ( text )
598 	    { free( text );	}
599 	}
600 
601     return 0;
602     }
603 
docRtfShapePropertyName(const RtfControlWord * rcw,int arg,RtfReader * rr)604 int docRtfShapePropertyName(	const RtfControlWord *	rcw,
605 				int			arg,
606 				RtfReader *		rr )
607     {
608     return docRtfReadGroup( rcw, 0, 0, rr, (RtfControlWord *)0,
609 					    docRtfSaveDocEncodedText,
610 					    docRtfCommitShapePropertyName );
611     }
612 
613 static RtfControlWord	docRtfReadPictValueGroups[]=
614     {
615 	RTF_DEST_XX( RTFtag_pict,	0,	docRtfReadShapePicture ),
616 
617 	{ (char *)0, 0, 0 }
618     };
619 
docRtfShapePropertyValue(const RtfControlWord * rcw,int arg,RtfReader * rr)620 int docRtfShapePropertyValue(	const RtfControlWord *	rcw,
621 				int			arg,
622 				RtfReader *		rr )
623     {
624     return docRtfReadGroup( rcw, 0, 0, rr, docRtfReadPictValueGroups,
625 					    docRtfSaveDocEncodedText,
626 					    docRtfCommitShapePropertyValue );
627     }
628 
629 /************************************************************************/
630 /*									*/
631 /*  Read shape instructions.						*/
632 /*									*/
633 /************************************************************************/
634 
635 static RtfControlWord	docRtfShpinstGroups[]=
636     {
637 	RTF_DEST_XX( "shptxt",	DOCinSHPTXT,	docRtfShpText ),
638 	RTF_DEST_XX( "sp",	1,		docRtfShapeProperty ),
639 	RTF_DEST_XX( "shpgrp",	SHPtyGROUP,	docRtfReadChildShape ),
640 	RTF_DEST_XX( "shp",	SHPtyUNKNOWN,	docRtfReadChildShape ),
641 
642 	{ (char *)0, 0, 0 }
643     };
644 
docRtfShpinst(const RtfControlWord * rcw,int arg,RtfReader * rr)645 static int docRtfShpinst(	const RtfControlWord *	rcw,
646 				int			arg,
647 				RtfReader *		rr )
648     {
649     int		res;
650 
651     res= docRtfReadGroup( rcw, 0, 0, rr,
652 		    docRtfShpinstGroups, docRtfIgnoreText, (RtfCommitGroup)0 );
653     if  ( res )
654 	{ SLDEB(rcw->rcwWord,res);	}
655 
656     return res;
657     }
658 
659 /************************************************************************/
660 /*									*/
661 /*  Read the shape result and immediately discard it.			*/
662 /*									*/
663 /************************************************************************/
664 
docRtfShprslt(const RtfControlWord * rcw,int arg,RtfReader * rr)665 static int docRtfShprslt(	const RtfControlWord *	rcw,
666 				int			arg,
667 				RtfReader *		rr )
668     {
669     int		res= 0;
670 
671     BufferItem *	sectBi;
672     SelectionScope	ss;
673     int			treeType= DOCinSHPTXT;
674     const int		ignoreEmpty= 0;
675 
676     DocumentTree	dt;
677 
678     rr->rrcInIgnoredGroup++;
679 
680     docInitDocumentTree( &dt );
681     docInitSelectionScope( &ss );
682 
683     sectBi= docGetSectNode( rr->rrcNode );
684     if  ( ! sectBi )
685 	{ XDEB(sectBi); res= -1; goto ready;	}
686 
687     ss.ssTreeType= DOCinSHPTXT;
688     ss.ssSectNr= 0;
689     ss.ssOwnerSectNr= sectBi->biNumberInParent;
690 
691     if  ( docRtfReadDocumentTree( rcw, &dt, &treeType,
692 						rr, ignoreEmpty, &ss ) )
693 	{ SDEB(rcw->rcwWord); res= -1; goto ready;	}
694 
695     docSetTreeTypeOfNode( dt.dtRoot, treeType );
696 
697   ready:
698 
699     docCleanDocumentTree( rr->rrDocument, &dt );
700     rr->rrcInIgnoredGroup--;
701 
702     return res;
703     }
704 
705 /************************************************************************/
706 /*									*/
707 /*  Read a shape or a drawing object that is translayed to a shape.	*/
708 /*									*/
709 /************************************************************************/
710 
docRtfReadShapeIntern(DrawingShape ** pDs,const RtfControlWord * rcw,int arg,RtfReader * rr,const RtfControlWord * shapeGroups)711 static int docRtfReadShapeIntern(	DrawingShape **		pDs,
712 					const RtfControlWord *	rcw,
713 					int			arg,
714 					RtfReader *		rr,
715 					const RtfControlWord *	shapeGroups )
716     {
717     int			res;
718     DrawingShape *	parent= rr->rrDrawingShape;
719     DrawingShape *	ds= (DrawingShape *)0;
720 
721     if  ( ! docRtfGetParaNode( rr ) )
722 	{ SDEB(rcw->rcwWord); return -1; }
723 
724     if  ( ! rr->rrcInIgnoredGroup )
725 	{
726 	const BufferItem *		bodySectBi;
727 
728 	ds= docClaimDrawingShape( &(rr->rrDocument->bdShapeList) );
729 	if  ( ! ds )
730 	    { XDEB(ds); return -1;	}
731 
732 	ds->dsDrawing.sdShapeType= rcw->rcwID;
733 
734 	bodySectBi= docGetBodySectNode( rr->rrcNode, rr->rrDocument );
735 	if  ( ! bodySectBi )
736 	    { XDEB(bodySectBi); return -1;	}
737 
738 	ds->dsSelectionScope.ssTreeType= DOCinSHPTXT;
739 	ds->dsSelectionScope.ssSectNr= 0;
740 	ds->dsSelectionScope.ssOwnerSectNr= bodySectBi->biNumberInParent;
741 	ds->dsSelectionScope.ssOwnerNumber= ds->dsShapeNumber;
742 
743 	rr->rrDrawingShape= ds;
744 	}
745 
746     res= docRtfReadGroup( rcw, 0, 0, rr,
747 			shapeGroups, docRtfIgnoreText, (RtfCommitGroup)0 );
748 
749     if  ( res )
750 	{
751 	SLDEB(rcw->rcwWord,res);
752 	if  ( ds )
753 	    { docDeleteDrawingShape( rr->rrDocument, ds );	}
754 	}
755     else{
756 	if  ( ! rr->rrcInIgnoredGroup )
757 	    {
758 	    BufferItem *	paraBi= rr->rrcNode;
759 	    TextParticule *	tp;
760 	    RtfReadingState *	rrs= rr->rrcState;
761 
762 	    if  ( rrs->rrsTextShadingChanged )
763 		{ docRtfRefreshTextShading( rr, rrs );	}
764 
765 	    tp= docAppendObject( rr->rrDocument, paraBi,
766 						    &(rrs->rrsTextAttribute) );
767 	    if  ( ! tp )
768 		{
769 		LDEB(paraBi->biParaParticuleCount);
770 		docDeleteDrawingShape( rr->rrDocument, ds );
771 		res= -1;
772 		}
773 	    else{
774 		InsertedObject *	io;
775 
776 		io= docGetObject( rr->rrDocument, tp->tpObjectNumber );
777 		if  ( ! io )
778 		    { LXDEB(tp->tpObjectNumber,io); res= -1;	}
779 		else{
780 		    io->ioKind= DOCokDRAWING_SHAPE;
781 		    io->ioDrawingShape= ds;
782 		    io->ioInline= 0;
783 		    }
784 
785 		}
786 	    *pDs= ds;
787 	    }
788 	}
789 
790     rr->rrDrawingShape= parent;
791     return res;
792     }
793 
794 /************************************************************************/
795 /*									*/
796 /*  The actual shape as opposed to the result in simpler RTF.		*/
797 /*									*/
798 /************************************************************************/
799 
800 static RtfControlWord	docRtfShapeGroups[]=
801     {
802 	RTF_DEST_XX( "shptxt",	DOCinSHPTXT,	docRtfShpText ),
803 	RTF_DEST_XX( "shprslt",	DOCinSHPTXT,	docRtfShprslt ),
804 	RTF_DEST_XX( "shpgrp",	SHPtyGROUP,	docRtfReadChildShape ),
805 	RTF_DEST_XX( "shp",	SHPtyUNKNOWN,	docRtfReadChildShape ),
806 	RTF_DEST_XX( "shpinst",	SHPtyUNKNOWN,	docRtfShpinst ),
807 
808 	{ (char *)0, 0, 0, }
809     };
810 
docRtfReadChildShape(const RtfControlWord * rcw,int arg,RtfReader * rr)811 static int docRtfReadChildShape(	const RtfControlWord *	rcw,
812 					int			arg,
813 					RtfReader *		rr )
814     {
815     int			res;
816     DrawingShape *	parent= rr->rrDrawingShape;
817     DrawingShape *	ds;
818 
819     if  ( ! rr->rrcInIgnoredGroup )
820 	{
821 	ds= docClaimShapeInParent( &(rr->rrDocument->bdShapeList),
822 						    parent, -1, rcw->rcwID );
823 	if  ( ! ds )
824 	    { XDEB(ds); return -1;	}
825 
826 	ds->dsDrawing.sdShapeType= rcw->rcwID;
827 
828 	ds->dsSelectionScope= parent->dsSelectionScope;
829 	ds->dsSelectionScope.ssOwnerNumber= ds->dsShapeNumber;
830 
831 	rr->rrDrawingShape= ds;
832 	}
833 
834     res= docRtfReadGroup( rcw, 0, 0, rr,
835 		    docRtfShapeGroups, docRtfIgnoreText, (RtfCommitGroup)0 );
836 
837     if  ( res )
838 	{ SLDEB(rcw->rcwWord,res);	}
839 
840     rr->rrDrawingShape= parent;
841     return res;
842     }
843 
docRtfReadShape(const RtfControlWord * rcw,int arg,RtfReader * rr)844 int docRtfReadShape(			const RtfControlWord *	rcw,
845 					int			arg,
846 					RtfReader *		rr )
847     {
848     DrawingShape *	ds= (DrawingShape *)0;
849 
850     if  ( ! docRtfGetParaNode( rr ) )
851 	{ SDEB(rcw->rcwWord); return -1; }
852 
853     return docRtfReadShapeIntern( &ds, rcw, arg, rr, docRtfShapeGroups );
854     }
855 
856 /************************************************************************/
857 /*									*/
858 /*  Make fixes to a shape that originates from reading a drawing	*/
859 /*  object.								*/
860 /*									*/
861 /*  1)  Word only uses the vertex in a drawing object to determine	*/
862 /*	what diagonal to draw.						*/
863 /*  2)  Word swaps the arrow heads. Why?				*/
864 /*									*/
865 /************************************************************************/
866 
docRtfDrawingObjectToShape(DrawingShape * ds)867 static int docRtfDrawingObjectToShape(	DrawingShape *	ds )
868     {
869     ShapeDrawing *		sd= &(ds->dsDrawing);
870 
871     if  ( ds->dsDrawing.sdShapeType == SHPtyLINE	&&
872 	  ! ds->dsIsChildShape				&&
873 	  sd->sdVertexCount == 2			)
874 	{
875 	ShapeArrow		sa;
876 
877 	/*  1  */
878 	if  ( sd->sdVertices[0].x <= sd->sdVertices[1].x )
879 	    { sd->sd_fFlipH= 0;	}
880 	else{ sd->sd_fFlipH= 1;	}
881 	if  ( sd->sdVertices[0].y <= sd->sdVertices[1].y )
882 	    { sd->sd_fFlipV= 0;	}
883 	else{ sd->sd_fFlipV= 1;	}
884 
885 	/*  2  */
886 	sa= sd->sdLineHeadArrow;
887 	sd->sdLineHeadArrow= sd->sdLineTailArrow;
888 	sd->sdLineTailArrow= sa;
889 	}
890 
891     return 0;
892     }
893 
894 static RtfControlWord	docRtfDoGroups[]=
895     {
896 	RTF_DEST_XX( "dptxbxtext",	DOCinSHPTXT,	docRtfShpText ),
897 
898 	{ (char *)0, 0, 0 }
899     };
900 
docRtfReadDrawingObject(const RtfControlWord * rcw,int arg,RtfReader * rr)901 int docRtfReadDrawingObject(	const RtfControlWord *	rcw,
902 				int			arg,
903 				RtfReader *	rr )
904     {
905     DrawingShape *	ds= (DrawingShape *)0;
906 
907     if  ( docRtfReadShapeIntern( &ds, rcw, arg, rr, docRtfDoGroups ) )
908 	{ SDEB(rcw->rcwWord);	}
909 
910     if  ( ! rr->rrcInIgnoredGroup )
911 	{
912 	if  ( docRtfDrawingObjectToShape( ds ) )
913 	    { LDEB(1);	}
914 	}
915 
916     return 0;
917     }
918 
919