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