1 /************************************************************************/
2 /* */
3 /* Buffer administration routines. */
4 /* */
5 /************************************************************************/
6
7 # include "docBaseConfig.h"
8
9 # include <stdlib.h>
10
11 # include <appDebugon.h>
12
13 # include "docRowProperties.h"
14 # include "docPropVal.h"
15
16 /************************************************************************/
17
18 static const int DocRowIntProperties[]=
19 {
20 RPpropGAP_WIDTH,
21 RPpropLEFT_INDENT,
22 RPpropHEIGHT,
23 RPpropALIGNMENT,
24 RPpropIS_TABLE_HEADER,
25 RPpropKEEP_ON_ONE_PAGE,
26 RPprop_KEEPFOLLOW,
27 RPpropAUTOFIT,
28 RPpropRTOL,
29 RPpropTRW_WIDTH,
30 RPpropTRFTS_WIDTH,
31 RPpropTRSPDL,
32 RPpropTRSPDR,
33 RPpropTRSPDT,
34 RPpropTRSPDB,
35 RPpropTRSPDFL,
36 RPpropTRSPDFR,
37 RPpropTRSPDFT,
38 RPpropTRSPDFB,
39 RPpropTRPADDL,
40 RPpropTRPADDR,
41 RPpropTRPADDT,
42 RPpropTRPADDB,
43 RPpropTRPADDFL,
44 RPpropTRPADDFR,
45 RPpropTRPADDFT,
46 RPpropTRPADDFB,
47 RPpropTRW_WIDTHB,
48 RPpropTRW_WIDTHA,
49 RPpropTRFTS_WIDTHB,
50 RPpropTRFTS_WIDTHA,
51 };
52
53 static const int DocRowIntPropertyCount=
54 sizeof(DocRowIntProperties)/sizeof(int);
55
56 static const int DocRowBorderProperties[]=
57 {
58 RPpropTOP_BORDER,
59 RPpropBOTTOM_BORDER,
60 RPpropLEFT_BORDER,
61 RPpropRIGHT_BORDER,
62 RPpropHORIZ_BORDER,
63 RPpropVERT_BORDER,
64 };
65
66 static const int DocRowBorderPropertyCount=
67 sizeof(DocRowBorderProperties)/sizeof(int);
68
69 /************************************************************************/
70 /* */
71 /* Initialise row properties. */
72 /* */
73 /************************************************************************/
74
docCleanRowProperties(RowProperties * rp)75 void docCleanRowProperties( RowProperties * rp )
76 {
77 if ( rp->rpCells )
78 { free( rp->rpCells ); }
79 }
80
docInitRowProperties(RowProperties * rp)81 void docInitRowProperties( RowProperties * rp )
82 {
83 rp->rpCellCount= 0;
84 rp->rpCells= (CellProperties *)0;
85
86 rp->rpHalfGapWidthTwips= 0;
87 rp->rpHeightTwips= 0;
88 rp->rpLeftIndentTwips= 0;
89
90 rp->rpIsTableHeader= 0;
91 rp->rpKeepOnOnePage= 0;
92 rp->rp_Keepfollow= 0;
93 rp->rpAutofit= 0;
94 rp->rpRToL= 0;
95
96 rp->rpTopBorderNumber= 0;
97 rp->rpBottomBorderNumber= 0;
98 rp->rpLeftBorderNumber= 0;
99 rp->rpRightBorderNumber= 0;
100 rp->rpHorizontalBorderNumber= 0;
101 rp->rpVerticalBorderNumber= 0;
102
103 rp->rpShadingNumber= 0;
104 rp->rpFrameNumber= 0;
105
106 rp->rpAlignment= DOCthaLEFT;
107
108 /**/
109 rp->rpPreferredWidth= 0;
110 rp->rpPreferredWidthUnit= TRautoNONE;
111
112 /**/
113 rp->rpLeftDefaultCellSpacing= 0;
114 rp->rpRightDefaultCellSpacing= 0;
115 rp->rpTopDefaultCellSpacing= 0;
116 rp->rpBottomDefaultCellSpacing= 0;
117
118 rp->rpLeftDefaultCellSpacingUnit= TRautoNONE;
119 rp->rpRightDefaultCellSpacingUnit= TRautoNONE;
120 rp->rpTopDefaultCellSpacingUnit= TRautoNONE;
121 rp->rpBottomDefaultCellSpacingUnit= TRautoNONE;
122
123 /**/
124 rp->rpLeftCellPadding= 0;
125 rp->rpRightCellPadding= 0;
126 rp->rpTopCellPadding= 0;
127 rp->rpBottomCellPadding= 0;
128
129 rp->rpLeftCellPaddingUnit= TRautoNONE;
130 rp->rpRightCellPaddingUnit= TRautoNONE;
131 rp->rpTopCellPaddingUnit= TRautoNONE;
132 rp->rpBottomCellPaddingUnit= TRautoNONE;
133
134 /**/
135 rp->rpCellWidthBefore= 0;
136 rp->rpCellWidthAfter= 0;
137
138 rp->rpCellWidthBeforeUnit= TRautoNONE;
139 rp->rpCellWidthAfterUnit= TRautoNONE;
140
141 /**/
142 rp->rpRowNumber= -1;
143 rp->rpRowBandNumber= -1;
144 rp->rpRowStyle= -1;
145
146 rp->rpIsLastRow= 0;
147 rp->rpAuthor= -1;
148
149 return;
150 }
151
152 /************************************************************************/
153 /* */
154 /* Insert the description of a column into those for a row. */
155 /* */
156 /* If we are asked to shift the columns to the right, shift them by */
157 /* the width of the new column. I.E. Its new right hand position minus */
158 /* the left hand position of the first cell that it will push to the */
159 /* right. This value is not influenced by the operation. */
160 /* */
161 /************************************************************************/
162
docInsertRowColumn(RowProperties * rp,int col,int shiftTail,const CellProperties * cp,const DocumentAttributeMap * dam)163 int docInsertRowColumn( RowProperties * rp,
164 int col,
165 int shiftTail,
166 const CellProperties * cp,
167 const DocumentAttributeMap * dam )
168 {
169 int i;
170 CellProperties * fresh;
171 int shiftTailBy= 0;
172
173 fresh= (CellProperties *)realloc( rp->rpCells,
174 (rp->rpCellCount+ 1)* sizeof(CellProperties) );
175 if ( ! fresh )
176 { LXDEB(rp->rpCellCount,fresh); return -1; }
177 rp->rpCells= fresh;
178
179 if ( col < 0 )
180 { col= rp->rpCellCount; }
181
182 if ( col < rp->rpCellCount && shiftTail )
183 {
184 shiftTailBy= cp->cpRightBoundaryTwips- docColumnLeft( rp, col );
185 }
186
187 for ( i= rp->rpCellCount; i > col; i-- )
188 {
189 docCopyCellProperties( fresh+ i, fresh+ i- 1, dam );
190 fresh[i].cpRightBoundaryTwips += shiftTailBy;
191 }
192
193 docInitCellProperties( fresh+ col );
194 docCopyCellProperties( fresh+ col, cp, dam );
195
196 rp->rpCellCount++;
197
198 return 0;
199 }
200
201 /************************************************************************/
202 /* */
203 /* Make a column wider (or narrower). */
204 /* */
205 /************************************************************************/
206
docRowPropertiesMakeColWider(RowProperties * rp,int col,int wider)207 int docRowPropertiesMakeColWider( RowProperties * rp,
208 int col,
209 int wider )
210 {
211 int i;
212 CellProperties * cp;
213
214 if ( col < 0 || col >= rp->rpCellCount )
215 { LLDEB(col,rp->rpCellCount); return -1; }
216
217 cp= rp->rpCells+ col;
218 for ( i= col; i < rp->rpCellCount; cp++, i++ )
219 { cp->cpRightBoundaryTwips += wider; }
220
221 return 0;
222 }
223
224 /************************************************************************/
225 /* */
226 /* Set the width of a range of columns. Space might have been stolen */
227 /* from a victim column that has become narrower. Also adjust its */
228 /* width. */
229 /* */
230 /************************************************************************/
231
docRowPropertiesSetWidth(RowProperties * rp,int col0,int col1,int wide,int victim,int victimWide)232 void docRowPropertiesSetWidth( RowProperties * rp,
233 int col0,
234 int col1,
235 int wide,
236 int victim,
237 int victimWide )
238 {
239 CellProperties * cp;
240 int col;
241
242 int ox0= rp->rpLeftIndentTwips;
243 int nx0= rp->rpLeftIndentTwips;
244
245 cp= rp->rpCells;
246 for ( col= 0; col < col0; cp++, col++ )
247 {
248 int ox1= cp->cpRightBoundaryTwips;
249 int w= cp->cpRightBoundaryTwips- ox0;
250
251 if ( col == victim )
252 { w= victimWide; }
253
254 ox0= ox1;
255 nx0= cp->cpRightBoundaryTwips= nx0+ w;
256 }
257
258 for ( col= col0; col <= col1; cp++, col++ )
259 {
260 int ox1= cp->cpRightBoundaryTwips;
261
262 ox0= ox1;
263 nx0= cp->cpRightBoundaryTwips= nx0+ wide;
264 }
265
266 for ( col= col1+ 1; col < rp->rpCellCount; cp++, col++ )
267 {
268 int ox1= cp->cpRightBoundaryTwips;
269 int w= cp->cpRightBoundaryTwips- ox0;
270
271 if ( col == victim )
272 { w= victimWide; }
273
274 ox0= ox1;
275 nx0= cp->cpRightBoundaryTwips= nx0+ w;
276 }
277
278 return;
279 }
280
281 /************************************************************************/
282 /* */
283 /* Calculate the width of a column. */
284 /* Calculate the left hand side coordinate. */
285 /* Calculate the right hand side coordinate. */
286 /* */
287 /************************************************************************/
288
docColumnWidth(const RowProperties * rp,int col)289 int docColumnWidth( const RowProperties * rp,
290 int col )
291 {
292 int left;
293
294 if ( col < 0 || col >= rp->rpCellCount )
295 { LLDEB(col,rp->rpCellCount); return -1; }
296
297 if ( col == 0 )
298 { left= rp->rpLeftIndentTwips; }
299 else{ left= rp->rpCells[col-1].cpRightBoundaryTwips; }
300
301 return rp->rpCells[col].cpRightBoundaryTwips- left;
302 }
303
docColumnLeft(const RowProperties * rp,int col)304 int docColumnLeft( const RowProperties * rp,
305 int col )
306 {
307 if ( col == 0 )
308 { return rp->rpLeftIndentTwips; }
309 else{
310 if ( col <= 0 || col > rp->rpCellCount )
311 { LLDEB(col,rp->rpCellCount); return -1; }
312
313 return rp->rpCells[col-1].cpRightBoundaryTwips;
314 }
315 }
316
docColumnRight(const RowProperties * rp,int col)317 int docColumnRight( const RowProperties * rp,
318 int col )
319 {
320 if ( col < 0 || col >= rp->rpCellCount )
321 { LLDEB(col,rp->rpCellCount); return -1; }
322
323 return rp->rpCells[col].cpRightBoundaryTwips;
324 }
325
docCellRight(int * pColspan,const RowProperties * rp,int col)326 int docCellRight( int * pColspan,
327 const RowProperties * rp,
328 int col )
329 {
330 int colspan= 1;
331 const CellProperties * cp= rp->rpCells+ col;
332 int right= cp->cpRightBoundaryTwips;
333
334 if ( cp->cpHorizontalMerge == CELLmergeHEAD )
335 {
336 int c;
337
338 for ( c= col+ 1; c < rp->rpCellCount; c++ )
339 {
340 if ( rp->rpCells[c].cpHorizontalMerge != CELLmergeFOLLOW )
341 { break; }
342
343 colspan++;
344 right= rp->rpCells[c].cpRightBoundaryTwips;
345 }
346 }
347
348 *pColspan= colspan;
349 return right;
350 }
351
352 /************************************************************************/
353 /* */
354 /* Delete a number of columns from row properties. */
355 /* */
356 /************************************************************************/
357
docDeleteColumnsFromRow(RowProperties * rp,int col0,int count,int shiftTail)358 int docDeleteColumnsFromRow( RowProperties * rp,
359 int col0,
360 int count,
361 int shiftTail )
362 {
363 int col1= col0+ count- 1;
364 int shiftBy= 0;
365 int col;
366
367 if ( col0+ count > rp->rpCellCount )
368 { LLLDEB(col0,count,rp->rpCellCount); return -1; }
369
370 if ( shiftTail )
371 {
372 int left= docColumnLeft( rp, col0 );
373
374 shiftBy= rp->rpCells[col1].cpRightBoundaryTwips- left;
375 }
376
377 rp->rpCellCount -= count;
378
379 for ( col= col0; col < rp->rpCellCount; col++ )
380 {
381 docCleanCellProperties( &(rp->rpCells[col]) );
382 rp->rpCells[col]= rp->rpCells[col+ count];
383 rp->rpCells[col].cpRightBoundaryTwips -= shiftBy;
384 }
385
386 return 0;
387 }
388
389 /************************************************************************/
390
docRowMaskToCellMask(PropertyMask * cellMask,const PropertyMask * rowMask)391 void docRowMaskToCellMask( PropertyMask * cellMask,
392 const PropertyMask * rowMask )
393 {
394 utilPropMaskClear( cellMask );
395
396 if ( PROPmaskISSET( rowMask, RPpropCELL_PROPS ) )
397 { utilPropMaskFill( cellMask, CLprop_COUNT ); }
398
399 if ( PROPmaskISSET( rowMask, RPpropCELL_LAYOUT ) )
400 { PROPmaskADD( cellMask, CLpropCELLX ); }
401 else{ PROPmaskUNSET( cellMask, CLpropCELLX ); }
402
403 return;
404 }
405
docRowMaskApplyCellMask(PropertyMask * rowMask,const PropertyMask * cellMask)406 void docRowMaskApplyCellMask( PropertyMask * rowMask,
407 const PropertyMask * cellMask )
408 {
409 if ( cellMask && ! utilPropMaskIsEmpty( cellMask ) )
410 {
411 PropertyMask cellMaskCopy= *cellMask;
412
413 if ( PROPmaskISSET( &cellMaskCopy, CLpropCELLX ) )
414 {
415 PROPmaskADD( rowMask, RPpropCELL_LAYOUT );
416 PROPmaskUNSET( &cellMaskCopy, CLpropCELLX );
417 }
418
419 if ( ! utilPropMaskIsEmpty( &cellMaskCopy ) )
420 { PROPmaskADD( rowMask, RPpropCELL_PROPS ); }
421 }
422
423 return;
424 }
425
426 /************************************************************************/
427 /* */
428 /* Compare row properties. */
429 /* */
430 /************************************************************************/
431
docRowPropertyDifference(PropertyMask * pRpDifPask,const RowProperties * rp1,const PropertyMask * rpCmpMask,const RowProperties * rp2,const DocumentAttributeMap * dam)432 void docRowPropertyDifference( PropertyMask * pRpDifPask,
433 const RowProperties * rp1,
434 const PropertyMask * rpCmpMask,
435 const RowProperties * rp2,
436 const DocumentAttributeMap * dam )
437 {
438 int p;
439 PropertyMask rpDifMask;
440
441 utilPropMaskClear( &rpDifMask );
442
443 if ( PROPmaskISSET( rpCmpMask, RPpropCELL_LAYOUT ) ||
444 PROPmaskISSET( rpCmpMask, RPpropCELL_PROPS ) )
445 {
446 int col;
447 const CellProperties * cp1;
448 const CellProperties * cp2;
449
450 if ( rp1->rpCellCount != rp2->rpCellCount )
451 {
452 PROPmaskADD( &rpDifMask, RPpropCELL_LAYOUT );
453 PROPmaskADD( &rpDifMask, RPpropCELL_PROPS );
454 }
455
456 cp1= rp1->rpCells;
457 cp2= rp2->rpCells;
458 for ( col= 0; col < rp1->rpCellCount && col < rp2->rpCellCount; cp1++, cp2++, col++ )
459 {
460 PropertyMask cpCmpMask;
461 PropertyMask cpDifMask;
462
463 docRowMaskToCellMask( &cpCmpMask, rpCmpMask );
464 utilPropMaskClear( &cpDifMask );
465
466 docCellPropertyDifference( &cpDifMask, cp1, &cpCmpMask, cp2, dam );
467 docRowMaskApplyCellMask( &rpDifMask, &cpDifMask );
468 }
469 }
470
471 for ( p= 0; p < DocRowIntPropertyCount; p++ )
472 {
473 int prop= DocRowIntProperties[p];
474
475 if ( PROPmaskISSET( rpCmpMask, prop ) )
476 {
477 int val1= docGetRowProperty( rp1, prop );
478 int val2= docGetRowProperty( rp2, prop );
479
480 if ( val1 != val2 )
481 { PROPmaskADD( &rpDifMask, prop ); }
482 }
483 }
484
485 for ( p= 0; p < DocRowBorderPropertyCount; p++ )
486 {
487 int prop= DocRowBorderProperties[p];
488
489 if ( PROPmaskISSET( rpCmpMask, prop ) )
490 {
491 int val1= docGetRowProperty( rp1, prop );
492 int val2= docGetRowProperty( rp2, prop );
493
494 if ( val2 >= 0 && dam && dam->damBorderMap )
495 { val2= dam->damBorderMap[val2]; }
496
497 if ( val1 != val2 )
498 { PROPmaskADD( &rpDifMask, prop ); }
499 }
500 }
501
502 /**/
503 if ( PROPmaskISSET( rpCmpMask, RPpropSHADING ) )
504 {
505 int fromNumber= rp2->rpShadingNumber;
506
507 if ( fromNumber >= 0 && dam && dam->damShadingMap )
508 { fromNumber= dam->damShadingMap[fromNumber]; }
509
510 if ( rp1->rpShadingNumber != fromNumber )
511 { PROPmaskADD( &rpDifMask, RPpropSHADING ); }
512 }
513
514 if ( PROPmaskISSET( rpCmpMask, RPpropFRAME ) )
515 {
516 int fromNumber= rp2->rpFrameNumber;
517
518 if ( fromNumber >= 0 && dam && dam->damFrameMap )
519 { fromNumber= dam->damFrameMap[fromNumber]; }
520
521 if ( rp1->rpFrameNumber != fromNumber )
522 { PROPmaskADD( &rpDifMask, RPpropFRAME ); }
523 }
524
525 *pRpDifPask= rpDifMask; return;
526 }
527
528 /************************************************************************/
529 /* */
530 /* Copy row properties. As this routine is not called very often, */
531 /* just call the 'update' routine. */
532 /* */
533 /************************************************************************/
534
docCopyRowProperties(RowProperties * rpTo,const RowProperties * rpFrom,const DocumentAttributeMap * dam)535 int docCopyRowProperties( RowProperties * rpTo,
536 const RowProperties * rpFrom,
537 const DocumentAttributeMap * dam )
538 {
539 PropertyMask rpDoneMask;
540 PropertyMask rpSetMask;
541
542 utilPropMaskClear( &rpDoneMask );
543 utilPropMaskClear( &rpSetMask );
544
545 utilPropMaskFill( &rpSetMask, RPprop_FULL_COUNT );
546
547 if ( docUpdRowProperties( &rpDoneMask, rpTo, &rpSetMask, rpFrom, dam ) )
548 { LDEB(1); return -1; }
549
550 return 0;
551 }
552
553 /************************************************************************/
554 /* */
555 /* 1) Are the columns in two RowProperties 'the same' (Do they */
556 /* align?) */
557 /* 2) All internal borders equal? */
558 /* 3) All column properties identical? */
559 /* */
560 /************************************************************************/
561
562 /* 1 */
docApproximatelyAlignedColumns(const RowProperties * rp1,const RowProperties * rp2)563 int docApproximatelyAlignedColumns( const RowProperties * rp1,
564 const RowProperties * rp2 )
565 {
566 CellProperties * cp1;
567 CellProperties * cp2;
568 int i;
569
570 const int D= 40;
571
572 if ( rp1->rpCellCount != rp2->rpCellCount )
573 { return 0; }
574
575 /* No!
576 if ( rp1->rpHalfGapWidthTwips != rp2->rpHalfGapWidthTwips )
577 { return 0; }
578 */
579
580 if ( rp1->rpLeftIndentTwips > rp2->rpLeftIndentTwips+ D ||
581 rp1->rpLeftIndentTwips < rp2->rpLeftIndentTwips- D )
582 { return 0; }
583
584 cp1= rp1->rpCells;
585 cp2= rp2->rpCells;
586 for ( i= 0; i < rp1->rpCellCount; cp2++, cp1++, i++ )
587 {
588 if ( cp1->cpRightBoundaryTwips > cp2->cpRightBoundaryTwips+ D ||
589 cp1->cpRightBoundaryTwips < cp2->cpRightBoundaryTwips- D )
590 { return 0; }
591 }
592
593 return 1;
594 }
595
596 /************************************************************************/
597 /* */
598 /* Change row properties and tell what has been changed. */
599 /* */
600 /************************************************************************/
601
docUpdRowProperties(PropertyMask * pRpDonePask,RowProperties * rpTo,const PropertyMask * rpSetMask,const RowProperties * rpFrom,const DocumentAttributeMap * dam)602 int docUpdRowProperties( PropertyMask * pRpDonePask,
603 RowProperties * rpTo,
604 const PropertyMask * rpSetMask,
605 const RowProperties * rpFrom,
606 const DocumentAttributeMap * dam )
607 {
608 int p;
609 PropertyMask rpDoneMask;
610
611 int updCellLayout;
612 int updCellProps;
613
614 updCellLayout= PROPmaskISSET( rpSetMask, RPpropCELL_LAYOUT );
615 updCellProps= PROPmaskISSET( rpSetMask, RPpropCELL_PROPS );
616
617 utilPropMaskClear( &rpDoneMask );
618
619 if ( updCellLayout || updCellProps )
620 {
621 int col;
622 CellProperties * cpTo;
623 const CellProperties * cpFrom;
624
625 if ( updCellLayout )
626 {
627 while( rpTo->rpCellCount > rpFrom->rpCellCount )
628 {
629 docCleanCellProperties( &(rpTo->rpCells[rpTo->rpCellCount-1]) );
630 PROPmaskADD( &rpDoneMask, RPpropCELL_LAYOUT );
631 if ( updCellProps )
632 { PROPmaskADD( &rpDoneMask, RPpropCELL_PROPS ); }
633 rpTo->rpCellCount--;
634 }
635 }
636
637 cpTo= rpTo->rpCells;
638 cpFrom= rpFrom->rpCells;
639 for ( col= 0;
640 col < rpTo->rpCellCount && col < rpFrom->rpCellCount;
641 cpTo++, cpFrom++, col++ )
642 {
643 PropertyMask cpSetMask;
644 PropertyMask cpDoneMask;
645
646 docRowMaskToCellMask( &cpSetMask, rpSetMask );
647 utilPropMaskClear( &cpDoneMask );
648
649 if ( docUpdCellProperties( &cpDoneMask, cpTo,
650 &cpSetMask, cpFrom, dam ) )
651 { LDEB(1); return -1; }
652
653 docRowMaskApplyCellMask( &rpDoneMask, &cpDoneMask );
654 }
655
656 if ( updCellLayout )
657 {
658 while( rpTo->rpCellCount < rpFrom->rpCellCount )
659 {
660 const int shiftTail= 0; /* at end: irrelevant */
661
662 if ( docInsertRowColumn( rpTo, rpTo->rpCellCount, shiftTail,
663 cpFrom, dam ) )
664 { LDEB(rpTo->rpCellCount); return -1; }
665
666 PROPmaskADD( &rpDoneMask, RPpropCELL_LAYOUT );
667 if ( updCellProps )
668 { PROPmaskADD( &rpDoneMask, RPpropCELL_PROPS ); }
669 cpFrom++;
670 }
671 }
672 }
673
674 for ( p= 0; p < DocRowIntPropertyCount; p++ )
675 {
676 int prop= DocRowIntProperties[p];
677
678 if ( PROPmaskISSET( rpSetMask, prop ) )
679 {
680 int valt= docGetRowProperty( rpTo, prop );
681 int valf= docGetRowProperty( rpFrom, prop );
682
683 if ( valt != valf )
684 {
685 if ( docSetRowProperty( rpTo, prop, valf ) )
686 { LLDEB(prop,valf); return -1; }
687
688 PROPmaskADD( &rpDoneMask, prop );
689 }
690 }
691 }
692
693 for ( p= 0; p < DocRowBorderPropertyCount; p++ )
694 {
695 int prop= DocRowBorderProperties[p];
696
697 if ( PROPmaskISSET( rpSetMask, prop ) )
698 {
699 int valt= docGetRowProperty( rpTo, prop );
700 int valf= docGetRowProperty( rpFrom, prop );
701
702 if ( valf >= 0 && dam && dam->damBorderMap )
703 { valf= dam->damBorderMap[valf]; }
704
705 if ( valt != valf )
706 {
707 if ( docSetRowProperty( rpTo, prop, valf ) )
708 { LLDEB(prop,valf); return -1; }
709
710 PROPmaskADD( &rpDoneMask, prop );
711 }
712 }
713 }
714
715 if ( PROPmaskISSET( rpSetMask, RPpropSHADING ) )
716 {
717 int fromNumber= rpFrom->rpShadingNumber;
718
719 if ( fromNumber >= 0 && dam && dam->damShadingMap )
720 { fromNumber= dam->damShadingMap[fromNumber]; }
721
722 if ( rpTo->rpShadingNumber != fromNumber )
723 {
724 rpTo->rpShadingNumber= fromNumber;
725 PROPmaskADD( &rpDoneMask, RPpropSHADING );
726 }
727 }
728
729 if ( PROPmaskISSET( rpSetMask, RPpropFRAME ) )
730 {
731 int fromNumber= rpFrom->rpFrameNumber;
732
733 if ( fromNumber >= 0 && dam && dam->damFrameMap )
734 { fromNumber= dam->damFrameMap[fromNumber]; }
735
736 if ( rpTo->rpFrameNumber != fromNumber )
737 {
738 rpTo->rpFrameNumber= fromNumber;
739 PROPmaskADD( &rpDoneMask, RPpropFRAME );
740 }
741 }
742
743 if ( pRpDonePask )
744 { utilPropMaskOr( pRpDonePask, pRpDonePask, &rpDoneMask ); }
745
746 return 0;
747 }
748
749 /************************************************************************/
750 /* */
751 /* Make a kind of 'default' row layout: Evenly distribute the */
752 /* available width over the columns. */
753 /* */
754 /************************************************************************/
755
docEqualWidthColumns(RowProperties * rp,int columns,int wide,int fontHalfPoints)756 int docEqualWidthColumns( RowProperties * rp,
757 int columns,
758 int wide,
759 int fontHalfPoints )
760 {
761 int rval= 0;
762 int col;
763
764 CellProperties cp;
765
766 const int shiftTail= 0; /* at end: irrelevant */
767
768 docInitCellProperties( &cp );
769
770 rp->rpHalfGapWidthTwips= 5* fontHalfPoints;
771 rp->rpLeftIndentTwips= -5* fontHalfPoints;
772
773 for ( col= 0; col < columns; col++ )
774 {
775 cp.cpRightBoundaryTwips= ( ( col+ 1 )* wide )/ columns;
776
777 if ( docInsertRowColumn( rp, col, shiftTail, &cp,
778 (const DocumentAttributeMap *)0 ) )
779 { LDEB(col); rval= -1; goto ready; }
780 }
781
782 ready:
783 docCleanCellProperties( &cp );
784
785 return rval;
786 }
787
docSetRowProperty(RowProperties * rp,int prop,int arg)788 int docSetRowProperty( RowProperties * rp,
789 int prop,
790 int arg )
791 {
792 switch( prop )
793 {
794 case RPpropGAP_WIDTH:
795 rp->rpHalfGapWidthTwips= arg;
796 break;
797
798 case RPpropLEFT_INDENT:
799 rp->rpLeftIndentTwips= arg;
800 break;
801
802 case RPpropHEIGHT:
803 rp->rpHeightTwips= arg;
804 break;
805
806 case RPpropTOP_BORDER:
807 rp->rpTopBorderNumber= arg;
808 break;
809 case RPpropBOTTOM_BORDER:
810 rp->rpBottomBorderNumber= arg;
811 break;
812 case RPpropLEFT_BORDER:
813 rp->rpLeftBorderNumber= arg;
814 break;
815 case RPpropRIGHT_BORDER:
816 rp->rpRightBorderNumber= arg;
817 break;
818 case RPpropHORIZ_BORDER:
819 rp->rpHorizontalBorderNumber= arg;
820 break;
821 case RPpropVERT_BORDER:
822 rp->rpVerticalBorderNumber= arg;
823 break;
824
825 case RPpropSHADING:
826 rp->rpShadingNumber= arg;
827 break;
828 case RPpropFRAME:
829 rp->rpFrameNumber= arg;
830 break;
831
832 /**/
833 case RPpropALIGNMENT:
834 rp->rpAlignment= arg;
835 break;
836
837 case RPpropIS_TABLE_HEADER:
838 rp->rpIsTableHeader= ( arg != 0 );
839 break;
840 case RPpropKEEP_ON_ONE_PAGE:
841 rp->rpKeepOnOnePage= ( arg != 0 );
842 break;
843 case RPprop_KEEPFOLLOW:
844 rp->rp_Keepfollow= ( arg != 0 );
845 break;
846 case RPpropAUTOFIT:
847 rp->rpAutofit= ( arg != 0 );
848 break;
849 case RPpropRTOL:
850 rp->rpRToL= ( arg != 0 );
851 break;
852
853 /**/
854 case RPpropTRW_WIDTH:
855 rp->rpPreferredWidth= arg;
856 break;
857 case RPpropTRFTS_WIDTH:
858 rp->rpPreferredWidthUnit= arg;
859 break;
860
861 /**/
862 case RPpropTRSPDL:
863 rp->rpLeftDefaultCellSpacing= arg;
864 break;
865 case RPpropTRSPDR:
866 rp->rpRightDefaultCellSpacing= arg;
867 break;
868 case RPpropTRSPDT:
869 rp->rpTopDefaultCellSpacing= arg;
870 break;
871 case RPpropTRSPDB:
872 rp->rpBottomDefaultCellSpacing= arg;
873 break;
874
875 case RPpropTRSPDFL:
876 rp->rpLeftDefaultCellSpacingUnit= arg;
877 break;
878 case RPpropTRSPDFR:
879 rp->rpRightDefaultCellSpacingUnit= arg;
880 break;
881 case RPpropTRSPDFT:
882 rp->rpTopDefaultCellSpacingUnit= arg;
883 break;
884 case RPpropTRSPDFB:
885 rp->rpBottomDefaultCellSpacingUnit= arg;
886 break;
887
888 /**/
889 case RPpropTRPADDL:
890 rp->rpLeftCellPadding= arg;
891 break;
892 case RPpropTRPADDR:
893 rp->rpRightCellPadding= arg;
894 break;
895 case RPpropTRPADDT:
896 rp->rpTopCellPadding= arg;
897 break;
898 case RPpropTRPADDB:
899 rp->rpBottomCellPadding= arg;
900 break;
901
902 case RPpropTRPADDFL:
903 rp->rpLeftCellPaddingUnit= arg;
904 break;
905 case RPpropTRPADDFR:
906 rp->rpRightCellPaddingUnit= arg;
907 break;
908 case RPpropTRPADDFT:
909 rp->rpTopCellPaddingUnit= arg;
910 break;
911 case RPpropTRPADDFB:
912 rp->rpBottomCellPaddingUnit= arg;
913 break;
914
915 /**/
916 case RPpropTRW_WIDTHB:
917 rp->rpCellWidthBefore= arg;
918 break;
919 case RPpropTRW_WIDTHA:
920 rp->rpCellWidthAfter= arg;
921 break;
922
923 case RPpropTRFTS_WIDTHB:
924 rp->rpCellWidthBeforeUnit= arg;
925 break;
926 case RPpropTRFTS_WIDTHA:
927 rp->rpCellWidthAfterUnit= arg;
928 break;
929
930 case RPpropAUTOFORMAT_BORDERS:
931 rp->rpAutoformatBorders= ( arg != 0 );
932 break;
933 case RPpropAUTOFORMAT_SHADING:
934 rp->rpAutoformatShading= ( arg != 0 );
935 break;
936 case RPpropAUTOFORMAT_FONT:
937 rp->rpAutoformatFont= ( arg != 0 );
938 break;
939 case RPpropAUTOFORMAT_COLOR:
940 rp->rpAutoformatColor= ( arg != 0 );
941 break;
942 case RPpropAUTOFORMAT_APPLY_BEST_FIT:
943 rp->rpAutoformatApplyBestFit= ( arg != 0 );
944 break;
945 case RPpropAUTOFORMAT_FIRST_ROW:
946 rp->rpAutoformatFirstRow= ( arg != 0 );
947 break;
948 case RPpropAUTOFORMAT_LAST_ROW:
949 rp->rpAutoformatLastRow= ( arg != 0 );
950 break;
951 case RPpropAUTOFORMAT_FIRST_COLUMN:
952 rp->rpAutoformatFirstColumn= ( arg != 0 );
953 break;
954 case RPpropAUTOFORMAT_LAST_COLUMN:
955 rp->rpAutoformatLastColumn= ( arg != 0 );
956 break;
957
958 case RPpropROW_NUMBER:
959 rp->rpRowNumber= arg;
960 break;
961 case RPpropROW_BAND_NUMBER:
962 rp->rpRowBandNumber= arg;
963 break;
964 case RPpropROW_STYLE:
965 rp->rpRowStyle= arg;
966 break;
967
968 case RPpropIS_LAST_ROW:
969 rp->rpIsLastRow= ( arg != 0 );
970 break;
971
972 case RPpropTRAUTH:
973 rp->rpAuthor= arg;
974 break;
975
976 case RPpropCELL_LAYOUT:
977 case RPpropCELL_PROPS:
978 default:
979 LDEB(prop); return -1;
980 }
981
982 return 0;
983 }
984
docGetRowProperty(const RowProperties * rp,int prop)985 int docGetRowProperty( const RowProperties * rp,
986 int prop )
987 {
988 switch( prop )
989 {
990 case RPpropGAP_WIDTH:
991 return rp->rpHalfGapWidthTwips;
992 break;
993
994 case RPpropLEFT_INDENT:
995 return rp->rpLeftIndentTwips;
996 break;
997
998 case RPpropHEIGHT:
999 return rp->rpHeightTwips;
1000 break;
1001
1002 case RPpropTOP_BORDER:
1003 return rp->rpTopBorderNumber;
1004 break;
1005 case RPpropBOTTOM_BORDER:
1006 return rp->rpBottomBorderNumber;
1007 break;
1008 case RPpropLEFT_BORDER:
1009 return rp->rpLeftBorderNumber;
1010 break;
1011 case RPpropRIGHT_BORDER:
1012 return rp->rpRightBorderNumber;
1013 break;
1014 case RPpropHORIZ_BORDER:
1015 return rp->rpHorizontalBorderNumber;
1016 break;
1017 case RPpropVERT_BORDER:
1018 return rp->rpVerticalBorderNumber;
1019 break;
1020
1021 case RPpropSHADING:
1022 return rp->rpShadingNumber;
1023 break;
1024 case RPpropFRAME:
1025 return rp->rpFrameNumber;
1026 break;
1027
1028 /**/
1029 case RPpropALIGNMENT:
1030 return rp->rpAlignment;
1031 break;
1032
1033 case RPpropIS_TABLE_HEADER:
1034 return rp->rpIsTableHeader;
1035 break;
1036 case RPpropKEEP_ON_ONE_PAGE:
1037 return rp->rpKeepOnOnePage;
1038 break;
1039 case RPprop_KEEPFOLLOW:
1040 return rp->rp_Keepfollow;
1041 break;
1042 case RPpropAUTOFIT:
1043 return rp->rpAutofit;
1044 break;
1045 case RPpropRTOL:
1046 return rp->rpRToL;
1047 break;
1048
1049 /**/
1050 case RPpropTRW_WIDTH:
1051 return rp->rpPreferredWidth;
1052 break;
1053 case RPpropTRFTS_WIDTH:
1054 return rp->rpPreferredWidthUnit;
1055 break;
1056
1057 /**/
1058 case RPpropTRSPDL:
1059 return rp->rpLeftDefaultCellSpacing;
1060 break;
1061 case RPpropTRSPDR:
1062 return rp->rpRightDefaultCellSpacing;
1063 break;
1064 case RPpropTRSPDT:
1065 return rp->rpTopDefaultCellSpacing;
1066 break;
1067 case RPpropTRSPDB:
1068 return rp->rpBottomDefaultCellSpacing;
1069 break;
1070
1071 case RPpropTRSPDFL:
1072 return rp->rpLeftDefaultCellSpacingUnit;
1073 break;
1074 case RPpropTRSPDFR:
1075 return rp->rpRightDefaultCellSpacingUnit;
1076 break;
1077 case RPpropTRSPDFT:
1078 return rp->rpTopDefaultCellSpacingUnit;
1079 break;
1080 case RPpropTRSPDFB:
1081 return rp->rpBottomDefaultCellSpacingUnit;
1082 break;
1083
1084 /**/
1085 case RPpropTRPADDL:
1086 return rp->rpLeftCellPadding;
1087 break;
1088 case RPpropTRPADDR:
1089 return rp->rpRightCellPadding;
1090 break;
1091 case RPpropTRPADDT:
1092 return rp->rpTopCellPadding;
1093 break;
1094 case RPpropTRPADDB:
1095 return rp->rpBottomCellPadding;
1096 break;
1097
1098 case RPpropTRPADDFL:
1099 return rp->rpLeftCellPaddingUnit;
1100 break;
1101 case RPpropTRPADDFR:
1102 return rp->rpRightCellPaddingUnit;
1103 break;
1104 case RPpropTRPADDFT:
1105 return rp->rpTopCellPaddingUnit;
1106 break;
1107 case RPpropTRPADDFB:
1108 return rp->rpBottomCellPaddingUnit;
1109 break;
1110
1111 /**/
1112 case RPpropTRW_WIDTHB:
1113 return rp->rpCellWidthBefore;
1114 break;
1115 case RPpropTRW_WIDTHA:
1116 return rp->rpCellWidthAfter;
1117 break;
1118
1119 case RPpropTRFTS_WIDTHB:
1120 return rp->rpCellWidthBeforeUnit;
1121 break;
1122 case RPpropTRFTS_WIDTHA:
1123 return rp->rpCellWidthAfterUnit;
1124 break;
1125
1126 case RPpropAUTOFORMAT_BORDERS:
1127 return rp->rpAutoformatBorders;
1128 break;
1129 case RPpropAUTOFORMAT_SHADING:
1130 return rp->rpAutoformatShading;
1131 break;
1132 case RPpropAUTOFORMAT_FONT:
1133 return rp->rpAutoformatFont;
1134 break;
1135 case RPpropAUTOFORMAT_COLOR:
1136 return rp->rpAutoformatColor;
1137 break;
1138 case RPpropAUTOFORMAT_APPLY_BEST_FIT:
1139 return rp->rpAutoformatApplyBestFit;
1140 break;
1141 case RPpropAUTOFORMAT_FIRST_ROW:
1142 return rp->rpAutoformatFirstRow;
1143 break;
1144 case RPpropAUTOFORMAT_LAST_ROW:
1145 return rp->rpAutoformatLastRow;
1146 break;
1147 case RPpropAUTOFORMAT_FIRST_COLUMN:
1148 return rp->rpAutoformatFirstColumn;
1149 break;
1150 case RPpropAUTOFORMAT_LAST_COLUMN:
1151 return rp->rpAutoformatLastColumn;
1152 break;
1153
1154 case RPpropROW_NUMBER:
1155 return rp->rpRowNumber;
1156 break;
1157 case RPpropROW_BAND_NUMBER:
1158 return rp->rpRowBandNumber;
1159 break;
1160 case RPpropROW_STYLE:
1161 return rp->rpRowStyle;
1162 break;
1163
1164 case RPpropIS_LAST_ROW:
1165 return rp->rpIsLastRow;
1166 break;
1167
1168 case RPpropTRAUTH:
1169 return rp->rpAuthor;
1170 break;
1171
1172 case RPpropCELL_LAYOUT:
1173 case RPpropCELL_PROPS:
1174 default:
1175 LDEB(prop); return -1;
1176 }
1177
1178 return 0;
1179 }
1180