Subversion Repositories Scribus

Rev

Rev 22631 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
16856 craig 1
/*
2
Copyright (C) 2011 Elvis Stansvik <elvstone@gmail.com>
3
 
4
For general Scribus (>=1.3.2) copyright and licensing information please refer
5
to the COPYING file provided with the program. Following this notice may exist
6
a copyright and/or license notice that predates the release of Scribus 1.3.2
7
for which a new license (GPL+exception) is in place.
8
*/
9
 
10
#include <QPointF>
11
 
25158 craig 12
#include "pageitem_table.h"
16856 craig 13
#include "tableborder.h"
14
#include "tableutils.h"
15
 
16
namespace TableUtils
17
{
18
 
17314 fschmid 19
void resolveBordersHorizontal(const TableCell& topLeftCell, const TableCell& topCell,
20
        const TableCell& topRightCell, const TableCell& bottomLeftCell, const TableCell& bottomCell,
21
        const TableCell& bottomRightCell, TableBorder* topLeft, TableBorder* left, TableBorder* bottomLeft,
22
        TableBorder* center, TableBorder* topRight, TableBorder* right, TableBorder* bottomRight, PageItem_Table* table)
23
{
24
        // Resolve top left.
25
        if (!topCell.isValid() && !bottomCell.isValid())
26
                return;
27
        if (topLeftCell.column() == topCell.column())
28
                *topLeft = TableBorder();
29
        else if (topLeftCell.isValid() && topCell.isValid())
30
                *topLeft = collapseBorders(topCell.leftBorder(), topLeftCell.rightBorder());
31
        else if (topLeftCell.isValid())
32
                *topLeft = collapseBorders(table->rightBorder(), topLeftCell.rightBorder());
33
        else if (topCell.isValid())
34
                *topLeft = collapseBorders(topCell.leftBorder(), table->leftBorder());
35
        else
36
                *topLeft = TableBorder();
37
        // Resolve left.
38
        if (topLeftCell.row() == bottomLeftCell.row())
39
                *left = TableBorder();
40
        else if (topLeftCell.isValid() && bottomLeftCell.isValid())
41
                *left = collapseBorders(bottomLeftCell.topBorder(), topLeftCell.bottomBorder());
42
        else if (topLeftCell.isValid())
43
                *left = collapseBorders(table->bottomBorder(), topLeftCell.bottomBorder());
44
        else if (bottomLeftCell.isValid())
45
                *left = collapseBorders(bottomLeftCell.topBorder(), table->topBorder());
46
        else
47
                *left = TableBorder();
48
        // Resolve bottom left.
49
        if (bottomLeftCell.column() == bottomCell.column())
50
                *bottomLeft = TableBorder();
51
        else if (bottomLeftCell.isValid() && bottomCell.isValid())
52
                *bottomLeft = collapseBorders(bottomCell.leftBorder(), bottomLeftCell.rightBorder());
53
        else if (bottomLeftCell.isValid())
54
                *bottomLeft = collapseBorders(table->rightBorder(), bottomLeftCell.rightBorder());
55
        else if (bottomCell.isValid())
56
                *bottomLeft = collapseBorders(bottomCell.leftBorder(), table->leftBorder());
57
        else
58
                *bottomLeft = TableBorder();
59
        // Resolve center.
60
        if (topCell.row() == bottomCell.row())
61
                *center = TableBorder();
62
        else if (topCell.isValid() && bottomCell.isValid())
63
                *center = collapseBorders(topCell.bottomBorder(), bottomCell.topBorder());
64
        else if (topCell.isValid())
65
                *center = collapseBorders(table->bottomBorder(), topCell.bottomBorder());
66
        else if (bottomCell.isValid())
67
                *center = collapseBorders(bottomCell.topBorder(), table->topBorder());
68
        else
69
                *center = TableBorder();
70
        // Resolve top right.
71
        if (topRightCell.column() == topCell.column())
72
                *topRight = TableBorder();
73
        else if (topRightCell.isValid() && topCell.isValid())
74
                *topRight = collapseBorders(topRightCell.leftBorder(), topCell.rightBorder());
75
        else if (topRightCell.isValid())
76
                *topRight = collapseBorders(topRightCell.leftBorder(), table->leftBorder());
77
        else if (topCell.isValid())
78
                *topRight = collapseBorders(table->rightBorder(), topCell.rightBorder());
79
        else
80
                *topRight = TableBorder();
81
        // Resolve right.
82
        if (topRightCell.row() == bottomRightCell.row())
83
                *right = TableBorder();
84
        else if (topRightCell.isValid() && bottomRightCell.isValid())
85
                *right = collapseBorders(bottomRightCell.topBorder(), topRightCell.bottomBorder());
86
        else if (topRightCell.isValid())
87
                *right = collapseBorders(table->bottomBorder(), topRightCell.bottomBorder());
88
        else if (bottomRightCell.isValid())
89
                *right = collapseBorders(bottomRightCell.topBorder(), table->topBorder());
90
        else
91
                *right = TableBorder();
92
        // Resolve bottom right.
93
        if (bottomRightCell.column() == bottomCell.column())
94
                *bottomRight = TableBorder();
95
        else if (bottomRightCell.isValid() && bottomCell.isValid())
96
                *bottomRight = collapseBorders(bottomRightCell.leftBorder(), bottomCell.rightBorder());
97
        else if (bottomRightCell.isValid())
98
                *bottomRight = collapseBorders(bottomRightCell.leftBorder(), table->leftBorder());
99
        else if (bottomCell.isValid())
100
                *bottomRight = collapseBorders(table->rightBorder(), bottomCell.rightBorder());
101
        else
102
                *bottomRight = TableBorder();
103
}
104
 
105
void resolveBordersVertical(const TableCell& topLeftCell, const TableCell& topRightCell, const TableCell& leftCell, const TableCell& rightCell, const TableCell& bottomLeftCell,
106
        const TableCell& bottomRightCell, TableBorder* topLeft, TableBorder* top, TableBorder* topRight, TableBorder* center, TableBorder* bottomLeft, TableBorder* bottom, TableBorder* bottomRight, PageItem_Table* table)
107
{
108
        if (!leftCell.isValid() && !rightCell.isValid())
109
                return;
110
        // Resolve top left.
111
        if (topLeftCell.row() == leftCell.row())
112
                *topLeft = TableBorder();
113
        else if (topLeftCell.isValid() && leftCell.isValid())
114
                *topLeft = collapseBorders(leftCell.topBorder(), topLeftCell.bottomBorder());
115
        else if (topLeftCell.isValid())
116
                *topLeft = collapseBorders(table->bottomBorder(), topLeftCell.bottomBorder());
117
        else if (leftCell.isValid())
118
                *topLeft = collapseBorders(leftCell.topBorder(), table->topBorder());
119
        else
120
                *topLeft = TableBorder();
121
        // Resolve top.
122
        if (topLeftCell.column() == topRightCell.column())
123
                *top = TableBorder();
124
        else if (topLeftCell.isValid() && topRightCell.isValid())
125
                *top = collapseBorders(topRightCell.leftBorder(), topLeftCell.rightBorder());
126
        else if (topLeftCell.isValid())
127
                *top = collapseBorders(table->rightBorder(), topLeftCell.rightBorder());
128
        else if (topRightCell.isValid())
129
                *top = collapseBorders(topRightCell.leftBorder(), table->leftBorder());
130
        else
131
                *top = TableBorder();
132
        // Resolve top right.
133
        if (topRightCell.row() == rightCell.row())
134
                *topRight = TableBorder();
135
        else if (topRightCell.isValid() && rightCell.isValid())
136
                *topRight = collapseBorders(rightCell.topBorder(), topRightCell.bottomBorder());
137
        else if (topRightCell.isValid())
138
                *topRight = collapseBorders(table->bottomBorder(), topRightCell.bottomBorder());
139
        else if (rightCell.isValid())
140
                *topRight = collapseBorders(rightCell.topBorder(), table->topBorder());
141
        else
142
                *topRight = TableBorder();
143
        // Resolve center.
144
        if (leftCell.column() == rightCell.column())
145
                *center = TableBorder();
146
        else if (leftCell.isValid() && rightCell.isValid())
147
                *center = collapseBorders(rightCell.leftBorder(), leftCell.rightBorder());
148
        else if (leftCell.isValid())
149
                *center = collapseBorders(table->rightBorder(), leftCell.rightBorder());
150
        else if (rightCell.isValid())
151
                *center = collapseBorders(rightCell.leftBorder(), table->leftBorder());
152
        else
153
                *center = TableBorder();
154
        // Resolve bottom left.
155
        if (bottomLeftCell.row() == leftCell.row())
156
                *bottomLeft = TableBorder();
157
        else if (bottomLeftCell.isValid() && leftCell.isValid())
158
                *bottomLeft = collapseBorders(bottomLeftCell.topBorder(), leftCell.bottomBorder());
159
        else if (bottomLeftCell.isValid())
160
                *bottomLeft = collapseBorders(bottomLeftCell.topBorder(), table->topBorder());
161
        else if (leftCell.isValid())
162
                *bottomLeft = collapseBorders(table->bottomBorder(), leftCell.bottomBorder());
163
        else
164
                *bottomLeft = TableBorder();
165
        // Resolve bottom.
166
        if (bottomLeftCell.column() == bottomRightCell.column())
167
                *bottom = TableBorder();
168
        else if (bottomLeftCell.isValid() && bottomRightCell.isValid())
169
                *bottom = collapseBorders(bottomRightCell.leftBorder(), bottomLeftCell.rightBorder());
170
        else if (bottomLeftCell.isValid())
171
                *bottom = collapseBorders(table->rightBorder(), bottomLeftCell.rightBorder());
172
        else if (bottomRightCell.isValid())
173
                *bottom = collapseBorders(bottomRightCell.leftBorder(), table->leftBorder());
174
        else
175
                *bottom = TableBorder();
176
        // Resolve bottom right.
177
        if (bottomRightCell.row() == rightCell.row())
178
                *bottomRight = TableBorder();
179
        else if (bottomRightCell.isValid() && rightCell.isValid())
180
                *bottomRight = collapseBorders(bottomRightCell.topBorder(), rightCell.bottomBorder());
181
        else if (bottomRightCell.isValid())
182
                *bottomRight = collapseBorders(bottomRightCell.topBorder(), table->topBorder());
183
        else if (rightCell.isValid())
184
                *bottomRight = collapseBorders(table->bottomBorder(), rightCell.bottomBorder());
185
        else
186
                *bottomRight = TableBorder();
187
}
188
 
16856 craig 189
TableBorder collapseBorders(const TableBorder& firstBorder, const TableBorder& secondBorder)
190
{
191
        TableBorder collapsedBorder;
192
 
193
        if (firstBorder.isNull() && secondBorder.isNull())
194
        {
195
                // Both borders are null, so return a null border.
196
                return collapsedBorder;
197
        }
22631 craig 198
        if (firstBorder.isNull())
16856 craig 199
        {
200
                // First border is null, so return second border.
201
                collapsedBorder = secondBorder;
202
        }
203
        else if (secondBorder.isNull())
204
        {
205
                // Second border is null, so return first border.
206
                collapsedBorder = firstBorder;
207
        }
208
        else
209
        {
210
                if (firstBorder.width() > secondBorder.width())
211
                {
212
                        // First border is wider than second border, so return first border.
213
                        collapsedBorder = firstBorder; // (4)
214
                }
215
                else if (firstBorder.width() < secondBorder.width())
216
                {
217
                        // Second border is wider than first border, so return second border.
218
                        collapsedBorder = secondBorder; // (5)
219
                }
220
                else
221
                {
222
                        if (firstBorder.borderLines().size() > secondBorder.borderLines().size())
223
                        {
224
                                // First border has more border lines than second border, so return first border.
225
                                collapsedBorder = firstBorder;
226
                        }
227
                        else
228
                        {
229
                                // Second border has more or equal border lines than first border, so return second border.
230
                                collapsedBorder = secondBorder;
231
                        }
232
                }
233
        }
234
 
235
        return collapsedBorder;
236
}
237
 
238
void joinVertical(const TableBorder& border, const TableBorder& topLeft, const TableBorder& top,
239
                                  const TableBorder& topRight, const TableBorder& bottomLeft, const TableBorder& bottom,
240
                                  const TableBorder& bottomRight, QPointF* start, QPointF* end, QPointF* startOffsetFactors,
241
                                  QPointF* endOffsetFactors)
242
{
243
        Q_ASSERT(start);
244
        Q_ASSERT(end);
245
        Q_ASSERT(startOffsetFactors);
246
        Q_ASSERT(endOffsetFactors);
247
 
248
        // Reset offset coefficients.
249
        startOffsetFactors->setX(0.0);
250
        startOffsetFactors->setY(0.0);
251
        endOffsetFactors->setX(0.0);
252
        endOffsetFactors->setY(0.0);
253
 
254
        /*
255
         * The numbered cases in the code below refers to the 45 possible join cases illustrated
256
         * in the picture at http://wiki.scribus.net/canvas/File:Table_border_join_cases.png
257
         */
258
 
259
        /*
260
         * Adjust start point(s). Possible cases are 1-20, 26-39.
261
         */
262
        if (border.joinsWith(topLeft))
263
        {
264
                if (border.joinsWith(topRight))
265
                {
266
                        if (!border.joinsWith(top))
267
                        {
268
                                // Cases: 8, 19.
269
                                startOffsetFactors->setY(-0.5);
270
                        }
271
                }
272
                else if (!border.joinsWith(top))
273
                {
274
                        if (top.joinsWith(topRight))
275
                        {
276
                                if (border.width() < top.width())
277
                                {
278
                                        // Cases: 15A.
279
                                        start->setY(start->y() + 0.5 * top.width());
280
                                }
281
                                else
282
                                {
283
                                        // Cases: 15B.
284
                                        startOffsetFactors->setY(-0.5);
285
                                }
286
                        }
287
                        else
288
                        {
289
                                // Cases: 5, 17, 27, 38.
290
                                startOffsetFactors->setY(-0.5);
291
                        }
292
                }
293
        }
294
        else if (border.joinsWith(topRight))
295
        {
296
                if (!border.joinsWith(top))
297
                {
298
                        if (top.joinsWith(topLeft))
299
                        {
300
                                if (border.width() < top.width())
301
                                {
302
                                        // Cases: 14A.
303
                                        start->setY(start->y() + 0.5 * top.width());
304
                                }
305
                                else
306
                                {
307
                                        // Cases: 14B.
308
                                        startOffsetFactors->setY(-0.5);
309
                                }
310
                        }
311
                        else
312
                        {
313
                                // Cases: 4, 18, 32, 36.
314
                                startOffsetFactors->setY(-0.5);
315
                        }
316
                }
317
        }
318
        else if (border.joinsWith(top))
319
        {
320
                if (topLeft.joinsWith(topRight))
321
                {
322
                        // Cases: 11.
323
                        start->setY(start->y() + 0.5 * topLeft.width());
324
                }
325
        }
326
        else
327
        {
328
                // Cases: 1, 2, 3, 6, 12, 16, 20, 26, 28, 31, 33, 37, 39.
329
                start->setY(start->y() + 0.5 * qMax(topLeft.width(), topRight.width()));
330
        }
331
        // Cases: 7, 9, 10, 13, 29, 30, 34, 35 - No adjustment to start point(s) needed.
332
 
333
        /*
334
         * Adjust end point(s). Possible cases are 1-15, 21-35, 40-43.
335
         */
336
        if (border.joinsWith(bottomLeft))
337
        {
338
                if (border.joinsWith(bottomRight))
339
                {
340
                        if (!border.joinsWith(bottom))
341
                        {
342
                                // Cases: 6, 24.
343
                                endOffsetFactors->setY(0.5);
344
                        }
345
                }
346
                else if (!border.joinsWith(bottom))
347
                {
348
                        if (bottom.joinsWith(bottomRight))
349
                        {
350
                                if (bottom.width() < border.width())
351
                                {
352
                                        // Cases: 14A.
353
                                        endOffsetFactors->setY(0.5);
354
                                }
355
                                else
356
                                {
357
                                        // Cases: 14B.
358
                                        end->setY(end->y() - 0.5 * bottom.width());
359
                                }
360
                        }
361
                        else
362
                        {
363
                                // Cases: 2, 22, 28, 42.
364
                                endOffsetFactors->setY(0.5);
365
                        }
366
                }
367
        }
368
        else if (border.joinsWith(bottomRight))
369
        {
370
                if (!border.joinsWith(bottom))
371
                {
372
                        if (bottom.joinsWith(bottomLeft))
373
                        {
374
                                if (bottom.width() < border.width())
375
                                {
376
                                        // Cases: 15A.
377
                                        endOffsetFactors->setY(0.5);
378
                                }
379
                                else
380
                                {
381
                                        // Cases: 15B.
382
                                        end->setY(end->y() - 0.5 * bottom.width());
383
                                }
384
                        }
385
                        else
386
                        {
387
                                // Cases: 3, 23, 33, 40.
388
                                endOffsetFactors->setY(0.5);
389
                        }
390
                }
391
        }
392
        else if (border.joinsWith(bottom))
393
        {
394
                if (bottomLeft.joinsWith(bottomRight))
395
                {
396
                        // Cases: 11.
397
                        end->setY(end->y() - 0.5 * bottomLeft.width());
398
                }
399
        }
400
        else
401
        {
402
                // Cases: 1, 4, 5, 8, 12, 21, 25, 26, 27, 31, 32, 41, 43.
403
                end->setY(end->y() - 0.5 * qMax(bottomLeft.width(), bottomRight.width()));
404
        }
405
        // Cases: 7, 9, 10, 13, 29, 30, 34, 35 - No adjustment to end point(s) needed.
406
}
407
 
408
void joinHorizontal(const TableBorder& border, const TableBorder& topLeft, const TableBorder& left,
409
                                  const TableBorder& bottomLeft, const TableBorder& topRight, const TableBorder& right,
410
                                  const TableBorder& bottomRight, QPointF* start, QPointF* end, QPointF* startOffsetFactors,
411
                                  QPointF* endOffsetFactors)
412
{
413
        Q_ASSERT(start);
414
        Q_ASSERT(end);
415
        Q_ASSERT(startOffsetFactors);
416
        Q_ASSERT(endOffsetFactors);
417
 
418
        // Reset offset coefficients.
419
        startOffsetFactors->setX(0.0);
420
        startOffsetFactors->setY(0.0);
421
        endOffsetFactors->setX(0.0);
422
        endOffsetFactors->setY(0.0);
423
 
424
        /*
425
         * The numbered cases in the code below refers to the 45 possible join cases illustrated
426
         * in the picture at http://wiki.scribus.net/canvas/File:Table_border_join_cases.png
427
         */
428
 
429
        /*
430
         * Adjust start point(s). Possible cases are 1-25, 31-37, 40-41.
431
         */
432
        if (border.joinsWith(bottomLeft))
433
        {
434
                if (border.joinsWith(topLeft))
435
                {
436
                        if (border.joinsWith(left))
437
                        {
438
                                // Cases: 10.
439
                                startOffsetFactors->setX(0.5);
440
                        }
441
                        else
442
                        {
443
                                // Cases: 7, 34.
444
                                startOffsetFactors->setX(0.5);
445
                        }
446
                }
447
                else
448
                {
449
                        if (border.joinsWith(left))
450
                        {
451
                                // Cases: 8, 19.
452
                                startOffsetFactors->setX(0.5);
453
                        }
454
                        else if (left.joinsWith(topLeft))
455
                        {
456
                                if (border.width() < left.width())
457
                                {
458
                                        // Cases: 14A.
459
                                        start->setX(start->x() + 0.5 * left.width());
460
                                }
461
                                else
462
                                {
463
                                        // Cases: 14B.
464
                                        startOffsetFactors->setX(0.5);
465
                                }
466
                        }
467
                        else
468
                        {
469
                                // Cases: 4, 18, 32, 36.
470
                                startOffsetFactors->setX(0.5);
471
                        }
472
                }
473
        }
474
        else if (border.joinsWith(topLeft))
475
        {
476
                if (border.joinsWith(left))
477
                {
478
                        // Cases: 6, 24.
479
                        startOffsetFactors->setX(0.5);
480
                }
481
                else
482
                {
483
                        if (left.joinsWith(bottomLeft))
484
                        {
485
                                if (left.width() < border.width())
486
                                {
487
                                        // Cases: 15A.
488
                                        startOffsetFactors->setX(0.5);
489
                                }
490
                                else
491
                                {
492
                                        // Cases: 15B.
493
                                        start->setX(start->x() + 0.5 * left.width());
494
                                }
495
                        }
496
                        else
497
                        {
498
                                // Cases: 3, 23, 33, 40.
499
                                startOffsetFactors->setX(0.5);
500
                        }
501
                }
502
        }
503
        else if (!border.joinsWith(left) &&
504
                         (topLeft.joinsWith(bottomLeft) || topLeft.joinsWith(left) || bottomLeft.joinsWith(left)))
505
        {
506
                // Cases: 2, 5, 9, 13, 17, 22, 35.
507
                start->setX(start->x() + 0.5 * qMax(topLeft.width(), bottomLeft.width()));
508
        }
509
        else if (left.isNull())
510
        {
511
                // Cases: 31, 37, 41.
512
                start->setX(start->x() - 0.5 * qMax(topLeft.width(), bottomLeft.width()));
513
        }
514
        // Cases: 1, 11, 12, 16, 20, 21, 25 - No adjustment to start point(s) needed.
515
 
516
        /*
517
         * Adjust end point(s). Possible cases are 1-30, 38-39, 42-43.
518
         */
519
        if (border.joinsWith(bottomRight))
520
        {
521
                if (border.joinsWith(topRight))
522
                {
523
                        if (border.joinsWith(right))
524
                        {
525
                                // Cases: 10.
526
                                endOffsetFactors->setX(-0.5);
527
                        }
528
                        else
529
                        {
530
                                // Cases: 9, 29.
531
                                endOffsetFactors->setX(-0.5);
532
                        }
533
                }
534
                else if (border.joinsWith(right))
535
                {
536
                        // Cases: 6, 24.
537
                        endOffsetFactors->setX(-0.5);
538
                }
539
                else
540
                {
541
                        if (right.joinsWith(topRight))
542
                        {
543
                                if (border.width() < right.width())
544
                                {
545
                                        // Cases: 15A.
546
                                        end->setX(end->x() - 0.5 * right.width());
547
                                }
548
                                else
549
                                {
550
                                        // Cases: 15B.
551
                                        endOffsetFactors->setX(-0.5);
552
                                }
553
                        }
554
                        else
555
                        {
556
                                // Cases: 5, 17, 27, 38.
557
                                endOffsetFactors->setX(-0.5);
558
                        }
559
                }
560
        }
561
        else if (border.joinsWith(topRight))
562
        {
563
                if (border.joinsWith(right))
564
                {
565
                        // Cases: 6, 24.
566
                        endOffsetFactors->setX(-0.5);
567
                }
568
                else
569
                {
570
                        if (right.joinsWith(bottomRight))
571
                        {
572
                                if (right.width() < border.width())
573
                                {
574
                                        // Cases: 14A.
575
                                        endOffsetFactors->setX(-0.5);
576
                                }
577
                                else
578
                                {
579
                                        // Cases: 14B.
580
                                        end->setX(end->x() - 0.5 * right.width());
581
                                }
582
                        }
583
                        else
584
                        {
585
                                // Cases: 2, 22, 28, 42.
586
                                endOffsetFactors->setX(-0.5);
587
                        }
588
                }
589
        }
590
        else if (!border.joinsWith(right) &&
591
                         (topRight.joinsWith(bottomRight) || topRight.joinsWith(right) || bottomRight.joinsWith(right)))
592
        {
593
                // Cases: 3, 4, 7, 13, 18, 23, 30.
594
                end->setX(end->x() - 0.5 * qMax(topRight.width(), bottomRight.width()));
595
        }
596
        else if (right.isNull())
597
        {
598
                // Cases: 26, 39, 43.
599
                end->setX(end->x() + 0.5 * qMax(topRight.width(), bottomRight.width()));
600
        }
601
        // Cases: 1, 11, 12, 16, 20, 21, 25 - No adjustment to end point(s) needed.
602
}
603
 
604
} // namespace TableUtils