Subversion Repositories Scribus

Rev

Rev 8094 | Rev 8097 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
4430 cbradney 1
/*
2
For general Scribus (>=1.3.2) copyright and licensing information please refer
3
to the COPYING file provided with the program. Following this notice may exist
4
a copyright and/or license notice that predates the release of Scribus 1.3.2
5
for which a new license (GPL+exception) is in place.
6
*/
3614 cbradney 7
/***************************************************************************
8
                          pageitem.cpp  -  description
9
                             -------------------
10
    begin                : Sat Apr 7 2001
11
    copyright            : (C) 2001 by Franz Schmid
12
    email                : Franz.Schmid@altmuehlnet.de
13
 ***************************************************************************/
14
 
15
/***************************************************************************
16
 *                                                                         *
17
 *   This program is free software; you can redistribute it and/or modify  *
18
 *   it under the terms of the GNU General Public License as published by  *
19
 *   the Free Software Foundation; either version 2 of the License, or     *
20
 *   (at your option) any later version.                                   *
21
 *                                                                         *
22
 ***************************************************************************/
23
 
24
#include "pageitem_textframe.h"
25
#include "pageitem_textframe.moc"
26
#include <qpainter.h>
27
#include <qpen.h>
28
#include <qfont.h>
29
#include <qregion.h>
30
#include <qpoint.h>
31
#include <qfileinfo.h>
32
#include <qdrawutil.h>
33
#include <qbitmap.h>
34
#include <qregexp.h>
35
#include <qmessagebox.h>
36
#include <cmath>
37
#include <cassert>
38
 
3829 cbradney 39
#include "hyphenator.h"
3614 cbradney 40
#include "mpalette.h"
41
#include "page.h"
42
#include "pageitem.h"
43
#include "prefsmanager.h"
44
#include "scpaths.h"
45
#include "scribus.h"
46
#include "scribusstructs.h"
47
#include "scribusdoc.h"
4145 cbradney 48
#include "selection.h"
3614 cbradney 49
#include "undomanager.h"
50
#include "undostate.h"
51
#include "scconfig.h"
4546 subik 52
#include "commonstrings.h"
5087 subik 53
#include "guidemanager.h"
3614 cbradney 54
 
55
#include "util.h"
5291 avox 56
#include "text/nlsconfig.h"
5756 jghali 57
#ifdef HAVE_CAIRO
58
#include <cairo.h>
59
#endif
3614 cbradney 60
 
61
using namespace std;
62
 
63
PageItem_TextFrame::PageItem_TextFrame(ScribusDoc *pa, double x, double y, double w, double h, double w2, QString fill, QString outline)
64
        : PageItem(pa, PageItem::TextFrame, x, y, w, h, w2, fill, outline)
65
{
3829 cbradney 66
        unicodeTextEditMode = false;
67
        unicodeInputCount = 0;
68
        unicodeInputString = "";
3614 cbradney 69
}
70
 
5184 avox 71
 
72
static QRegion itemShape(PageItem* docItem, ScribusView* view, double xOffset, double yOffset)
73
{
74
        QRegion res;
75
        QPainter pp;
76
        pp.begin(view->viewport());
77
        pp.translate(docItem->xPos() - xOffset, docItem->yPos() - yOffset);
78
        pp.rotate(docItem->rotation());
79
        if (docItem->textFlowUsesBoundingBox())
80
        {
81
                QPointArray tcli(4);
82
                tcli.setPoint(0, QPoint(0,0));
83
                tcli.setPoint(1, QPoint(qRound(docItem->width()), 0));
84
                tcli.setPoint(2, QPoint(qRound(docItem->width()), qRound(docItem->height())));
85
                tcli.setPoint(3, QPoint(0, qRound(docItem->height())));
86
                res = QRegion(pp.xForm(tcli));
87
        }
88
        else
89
        {
90
                if ((docItem->textFlowUsesContourLine()) && (docItem->ContourLine.size() != 0))
91
                {
92
                        QValueList<uint> Segs;
93
                        QPointArray Clip2 = FlattenPath(docItem->ContourLine, Segs);
94
                        res = QRegion(pp.xForm(Clip2));
95
                }
96
                else
97
                        res = QRegion(pp.xForm(docItem->Clip));
98
        }
99
        pp.end();
100
        return  res;
101
}
102
 
103
QRegion PageItem_TextFrame::availableRegion(QRegion clip)
104
{
7181 cbradney 105
        QRegion result(clip);
5184 avox 106
        if (!isEmbedded)
107
        {
7181 cbradney 108
                int LayerLev = m_Doc->layerLevelFromNumber(LayerNr);
109
                uint docItemsCount=m_Doc->Items->count();
110
                Page* Mp=0;
111
                Page* Dp=0;
112
                PageItem* docItem=0;
113
                int LayerLevItem;
5184 avox 114
                if (!OnMasterPage.isEmpty())
115
                {
5559 avox 116
                        if ((savedOwnPage == -1) || (savedOwnPage >= signed(m_Doc->Pages->count())))
5375 fschmid 117
                                return result;
7175 fschmid 118
                        Mp = m_Doc->MasterPages.at(m_Doc->MasterNames[OnMasterPage]);
119
                        Dp = m_Doc->Pages->at(savedOwnPage);
5184 avox 120
                        for (uint a = 0; a < m_Doc->MasterItems.count(); ++a)
121
                        {
7175 fschmid 122
                                docItem = m_Doc->MasterItems.at(a);
123
                                LayerLevItem = m_Doc->layerLevelFromNumber(docItem->LayerNr);
5359 fschmid 124
                                if (((docItem->ItemNr > ItemNr) && (docItem->LayerNr == LayerNr)) || (LayerLevItem > LayerLev) && (m_Doc->layerFlow(docItem->LayerNr)))
5184 avox 125
                                {
5620 jghali 126
                                        if (docItem->textFlowAroundObject())
5184 avox 127
                                        {
128
                                                result = result.subtract(itemShape(docItem, m_Doc->view(),  Mp->xOffset() - Dp->xOffset(), Mp->yOffset() - Dp->yOffset()));
129
                                        }
5387 avox 130
                                }
131
                        } // for all masterItems
5184 avox 132
                        if (!m_Doc->masterPageMode())
133
                        {
134
                                for (uint a = 0; a < docItemsCount; ++a)
135
                                {
7175 fschmid 136
                                        docItem = m_Doc->Items->at(a);
137
                                        Mp = m_Doc->MasterPages.at(m_Doc->MasterNames[OnMasterPage]);
138
                                        Dp = m_Doc->Pages->at(OwnPage);
5620 jghali 139
                                        if ((docItem->textFlowAroundObject()) && (docItem->OwnPage == OwnPage))
5184 avox 140
                                        {
141
                                                result = result.subtract(itemShape(docItem, m_Doc->view(), Mp->xOffset() - Dp->xOffset(), Mp->yOffset() - Dp->yOffset()));
142
                                        }
143
                                } // for all docItems
144
                        } // if (! masterPageMode)
5387 avox 145
                } // if (!OnMasterPage.isEmpty())
5184 avox 146
                else
147
                {
148
                        for (uint a = 0; a < docItemsCount; ++a)
149
                        {
7175 fschmid 150
                                docItem = m_Doc->Items->at(a);
151
                                LayerLevItem = m_Doc->layerLevelFromNumber(docItem->LayerNr);
5359 fschmid 152
                                if (((docItem->ItemNr > ItemNr) && (docItem->LayerNr == LayerNr)) || (LayerLevItem > LayerLev) && (m_Doc->layerFlow(docItem->LayerNr)))
5184 avox 153
                                {
5620 jghali 154
                                         if (docItem->textFlowAroundObject())
5229 fschmid 155
                                                result = result.subtract(itemShape(docItem, m_Doc->view(), 0, 0));
5387 avox 156
                                }
157
                        } // for all docItems
5184 avox 158
                        } // if(OnMasterPage.isEmpty()          
159
        } // if(!Embedded)
160
        return result;
161
}
162
 
6144 avox 163
 
164
void PageItem_TextFrame::setShadow()
165
{
166
        if (OnMasterPage.isEmpty())
167
                return;
6366 avox 168
 
6144 avox 169
        QString newShadow = m_Doc->masterPageMode() ? OnMasterPage : QString::number(OwnPage);
170
        if (newShadow != currentShadow) {
6366 avox 171
                if (currentShadow == OnMasterPage) {
172
                        // masterpage was edited, clear all shadows
173
                        shadows.clear();
174
                }
6144 avox 175
                if (!shadows.contains(newShadow)) {
176
                        if (!shadows.contains(OnMasterPage)) {
177
                                shadows[OnMasterPage] = itemText;
7905 avox 178
//                              const ParagraphStyle& pstyle(shadows[OnMasterPage].paragraphStyle(0));
7887 avox 179
//                              qDebug(QString("Pageitem_Textframe: style of master: %1 align=%2").arg(pstyle.parent()).arg(pstyle.alignment()));
6375 avox 180
//                              qDebug(QString("Pageitem_Textframe: shadow itemText->%1").arg(OnMasterPage));
6144 avox 181
                        }
7887 avox 182
                        if (newShadow != OnMasterPage) {
183
                                shadows[newShadow] = shadows[OnMasterPage].copy();
184
//                              const ParagraphStyle& pstyle(shadows[newShadow].paragraphStyle(0));
185
//                              qDebug(QString("Pageitem_Textframe: style of shadow copy: %1 align=%2").arg(pstyle.parent()).arg(pstyle.alignment()));
186
                        }
6375 avox 187
//                      qDebug(QString("Pageitem_Textframe: shadow %1<-%2").arg(newShadow).arg(OnMasterPage));
6144 avox 188
                }
189
                itemText = shadows[newShadow];
7887 avox 190
//              const ParagraphStyle& pstyle(itemText.paragraphStyle(0));
191
//              qDebug(QString("Pageitem_Textframe: style of shadow: %1 align=%2").arg(pstyle.parent()).arg(pstyle.alignment()));
6144 avox 192
                invalid = true;
193
                currentShadow = newShadow;
194
        }
195
}
196
 
5291 avox 197
#ifdef NLS_PROTO
198
#include "text/pageitem_textframe.cpp"
199
#else
200
 
5778 avox 201
static void dumpIt(const ParagraphStyle& pstyle, QString indent = QString("->"))
202
{
6805 avox 203
        qDebug(QString("%6%1/%2 @ %3: %4--%5 linespa%6: %7 align%8")
5778 avox 204
                   .arg(pstyle.name())
6733 avox 205
                   .arg(pstyle.parent())
5850 tsoots 206
                   .arg( (unsigned long int) &pstyle)
5778 avox 207
                   .arg(pstyle.leftMargin())
208
                   .arg(pstyle.rightMargin())
6805 avox 209
                   .arg(indent)
210
                   .arg(pstyle.lineSpacingMode())
211
                   .arg(pstyle.lineSpacing())
212
                   .arg(pstyle.alignment()));
5778 avox 213
        static QString more("  ");
6733 avox 214
        if (pstyle.hasParent())
215
                dumpIt(*dynamic_cast<const ParagraphStyle*>(pstyle.parentStyle()), more + indent);
5778 avox 216
}
217
 
5390 avox 218
 
7313 avox 219
static void layoutDropCap(GlyphLayout layout, double curX, double curY, double offsetX, double offsetY, double dropCapDrop)
220
{      
6370 avox 221
}
222
 
7905 avox 223
 
224
static void fillInTabLeaders(StoryText & itemText, LineSpec & curLine)
225
{
226
        // fill in tab leaders
227
        double xPos = curLine.x;
228
        for (int ti= curLine.firstItem; ti < curLine.lastItem; ++ti)
229
        {
230
                ScText * hl = itemText.item(ti);
231
                if (hl->ch[0] == SpecialChars::TAB)
232
                {
233
                        GlyphLayout * tglyph = hl->glyph.more;
234
 
235
                        if (!tglyph)
236
                                continue;
237
 
238
                        const CharStyle & charStyle(itemText.charStyle(ti));
239
                        double wt   = charStyle.font().glyphWidth(tglyph->glyph, charStyle.fontSize() * tglyph->scaleV / 10.0);
240
                        double len  = hl->glyph.xadvance;
241
                        int count   = static_cast<int>(len / wt);
242
                        double sPos = -len;
243
                        tglyph->xoffset = sPos;
244
//                      qDebug(QString("tab leaders: %1 %2 width=%3 count=%4").arg(sPos).arg(curLine.y).arg(wt).arg(count));
245
                        for (int cx = 1; cx < count; ++cx)
246
                        {
247
                                // clone fillchar
248
                                tglyph->grow();
249
                                *(tglyph->more) = *tglyph;
250
                                tglyph->more->more = NULL;
251
                                tglyph = tglyph->more;
252
                                tglyph->xoffset =  sPos + wt * cx;
253
                        }
254
                }
255
                xPos += hl->glyph.wide();
256
        }
257
}
258
 
259
 
7887 avox 260
static bool isBreakingSpace(QChar c)
261
{
262
        static const QChar blnk(' ');
263
        return c == blnk || c == SpecialChars::ZWSPACE;
264
}
265
 
266
static bool isExpandingSpace(QChar c)
267
{
268
        static const QChar blnk(' ');
269
        return c == blnk || c == SpecialChars::NBSPACE;
270
}
271
 
272
static bool isBreak(QChar c, bool includeColBreak = true)
273
{
274
        return (c == SpecialChars::PARSEP
275
                        || c == SpecialChars::LINEBREAK
276
                        || c == SpecialChars::FRAMEBREAK
277
                        || (includeColBreak && c == SpecialChars::COLBREAK));
278
}
279
 
280
 
7905 avox 281
enum TabStatus {
282
        TabNONE    = 0,
283
        TabLEFT    = TabNONE,
284
        TabRIGHT   = 1,
285
        TabPOINT   = 2,
286
        TabCOMMA   = 3,
287
        TabCENTER  = 4
7313 avox 288
};
6370 avox 289
 
7313 avox 290
struct TabControl {
291
        bool   active;
7905 avox 292
        int    status;
7313 avox 293
        int    charIndex;
294
        double xPos;
7905 avox 295
        QChar  fillChar;
7313 avox 296
};
297
 
298
struct LineControl {
299
        LineSpec line;
300
        int      itemsInLine;
301
        int      hyphenCount;
302
        double   colWidth;
8095 avox 303
        double   colGap;
7313 avox 304
        double   colLeft;
305
        double   colRight;
306
        int      column;
307
        bool     startOfCol;
308
        double   ascend;
309
        double   descend;
310
        double   width;
311
        double   xPos;
312
        double   yPos;
313
        int      breakIndex;
314
        double   breakXPos;
8095 avox 315
 
316
 
317
        void init(double w, double h, const MarginStruct& extra, double lCorr)
318
        {
319
                insets = extra;
320
                lineCorr = lCorr;
321
                frameWidth = w;
322
                frameHeight = h;
323
        }
324
 
325
        void initColumns(double width, double gap)
326
        {
327
                column = 0;
328
                colWidth = width;
329
                colGap = gap;
330
        }
331
 
332
        void nextColumn(double asce)
333
        {
334
                startOfCol = true;
335
                colLeft = (colWidth + colGap) * column + insets.Left + lineCorr;
336
                colRight = colLeft + colWidth;
337
//              colRight += insets.Right + lineCorr; //???
338
                xPos = colLeft;
339
                yPos = asce + insets.Top + lineCorr + 1;
340
        }
341
 
342
        bool isEndOfCol(double morespace = 0)
343
        {
344
                return yPos + morespace + insets.Bottom + lineCorr > frameHeight;
345
        }
346
 
347
        void startLine(int first)
348
        {              
349
                itemsInLine = 0;
350
                line.x = xPos;
351
                line.y = yPos;
352
                line.firstItem = first;
353
                line.ascent = 10;
354
                line.descent = 0;
355
                line.width = 0;
356
                line.naturalWidth = 0;
357
                breakIndex = -1;
358
                breakXPos = 0;
359
        }
360
 
361
        void rememberBreak(int index, double pos)
362
        {
363
                breakIndex = index;
364
                breakXPos = pos;
365
        }
366
 
367
 
368
        void breakLine(const StoryText& itemText, int last)
369
        {
370
                breakIndex = last;
371
                breakXPos  = line.x;
372
                for (int j = line.firstItem; j <= last; ++j)
373
                        if ( (itemText.item(j)->effects() & ScStyle_SuppressSpace) == 0)
374
                                breakXPos += itemText.item(j)->glyph.wide();
375
        }
376
 
377
        void finishLine(double endX)
378
        {
379
                line.lastItem = breakIndex;
380
                line.naturalWidth = breakXPos - line.x;
381
                line.width = endX - line.x;
382
        }
383
 
384
 
385
        bool isEndOfLine(double moreSpace = 0)
386
        {
387
//              return xPos + insets.Right + lineCorr + moreSpace > colRight;
388
                return xPos + lineCorr + moreSpace > colRight;
389
        }
390
 
391
        double startOfLine(const QRegion& shape, const QPainter& pf2, double ascent, double descent, double morespace)
392
        {
393
                QPoint pt1, pt2;
394
                double tmpX = xPos;
395
                pt1 = QPoint(static_cast<int>(ceil(tmpX)), static_cast<int>(yPos + descent));
396
                pt2 = QPoint(static_cast<int>(ceil(tmpX)), static_cast<int>(ceil(yPos - ascent)));
397
                // increase pt1/pt2 until i-beam reaches end of line
398
                while ((!shape.contains(pf2.xForm(pt1))) || (!shape.contains(pf2.xForm(pt2))))
399
                {
400
                        tmpX++;
401
                        if (isEndOfLine(morespace))
402
                        {
403
                                return tmpX;
404
                        }
405
                        pt1 = QPoint(static_cast<int>(ceil(tmpX)), static_cast<int>(yPos + descent));
406
                        pt2 = QPoint(static_cast<int>(ceil(tmpX)), static_cast<int>(ceil(yPos - ascent)));
407
                }
408
                return tmpX;
409
        }
410
 
411
        double endOfLine(const QRegion& shape, const QPainter& pf2, double ascent, double descent, double morespace = 0)
412
        {
413
                double EndX = floor(QMAX(line.x, breakXPos - 1));
414
                QPoint pt1, pt2;
415
                //      qDebug(QString("endx start=%1, hl is '%2'").arg(EndX).arg(hl->ch));
416
                do {
417
                        EndX += 0.125;
418
                        pt1 = QPoint(qRound(EndX + insets.Right), static_cast<int>(yPos+descent));
419
                        pt2 = QPoint(qRound(EndX + insets.Right), static_cast<int>(ceil(yPos-ascent)));
420
                } while
421
//                      (   (EndX + lineCorr  + insets.Right < colRight - morespace)
422
                        (   (EndX + lineCorr  < colRight - morespace)
423
                          && shape.contains(pf2.xForm(pt1))
424
                          && shape.contains(pf2.xForm(pt2))
425
                          );
426
 
427
                return EndX;
428
        }
429
 
430
 
431
private:
432
        double frameWidth;
433
        double frameHeight;
434
        MarginStruct insets;
435
        double lineCorr;
7313 avox 436
};
437
 
438
 
8095 avox 439
 
440
static void justifyLine(StoryText& itemText, LineSpec& line)
441
{
442
        // count the available spaces
443
        int aSpa = 0;
444
        double OFs2;
445
        for (int sof = line.firstItem; sof < line.lastItem; ++sof)
446
        {
447
                if (isExpandingSpace(itemText.text(sof))
448
                        && ! (itemText.item(sof)->effects() & ScStyle_SuppressSpace)
449
                        )
450
                        aSpa++;
451
        }
452
        if (aSpa != 0)
453
                OFs2 = (line.width - line.naturalWidth) / aSpa;
454
        else
455
                OFs2 = 0;
456
 
457
        // distribute whitespace on spaces
458
        for (int yof = line.firstItem; yof < line.lastItem; ++yof)
459
        {
460
                if (isExpandingSpace(itemText.text(yof))
461
                        && ! (itemText.item(yof)->effects() & ScStyle_SuppressSpace)
462
                        )
463
                {
464
                        itemText.item(yof)->glyph.last()->xadvance += OFs2;
465
                }
466
        }
467
}
468
 
469
 
470
static void indentLine(LineSpec& line, double leftIndent)
471
{
472
        line.x += leftIndent;
473
        line.width -= leftIndent;
474
}
475
 
476
static double opticalLeftMargin(const StoryText& itemText, const LineSpec& line)
477
{
478
        int b = line.firstItem;
479
        while (b < line.lastItem && (itemText.item(b)->effects() & ScStyle_SuppressSpace))
480
                   ++b;
481
 
482
        double chs = itemText.charStyle(b).fontSize() * (itemText.charStyle(b).scaleH() / 1000.0);
483
        QChar chr = itemText.text(b);
484
        double leftCorr = itemText.charStyle(b).font().realCharWidth(chr, chs / 10.0);
485
        if (QString("'´`").find(chr) >= 0
486
                || chr == QChar(0x2018)
487
                || chr == QChar(0x2019)
488
                || chr == QChar(0x201a)
489
                || chr == QChar(0x201b)
490
                || chr == QChar(0x2039)
491
                || chr == QChar(0x203a)
492
                )
493
                leftCorr *= -0.7;
494
        else if (QString("\"").find(chr) >= 0
495
                         || chr == QChar(0x00ab)
496
                         || chr == QChar(0x00bb)
497
                         || chr == QChar(0x201c)
498
                         || chr == QChar(0x201d)
499
                         || chr == QChar(0x201e)
500
                         || chr == QChar(0x201f)
501
                         )
502
                leftCorr *= -0.5;
503
        else {
504
                leftCorr = itemText.charStyle(b).font().charWidth(QChar(' '), chs / 10.0, chr);
505
                leftCorr -= itemText.charStyle(b).font().charWidth(QChar(' '), chs / 10.0);
506
//                              double leftCorr2 = itemText.charStyle(a).font().charWidth(QChar('K'), chs / 10.0, chr);
507
//                              leftCorr2 -= itemText.charStyle(a).font().charWidth(QChar('K'), chs / 10.0);
508
//                              leftCorr = QMIN(leftCorr, leftCorr2);
509
        }
510
        return leftCorr;
511
}
512
 
513
 
514
static double opticalRightMargin(const StoryText& itemText, const LineSpec& line)
515
{
516
        int b = line.lastItem;
517
        while (b > line.firstItem &&
518
                   (isBreakingSpace(itemText.text(b)) || isBreak(itemText.text(b)))
519
                   )
520
                --b;
521
        if (b >= line.firstItem)
522
        {
523
                double chs = itemText.charStyle(b).fontSize() * (itemText.charStyle(b).scaleH() / 1000.0);
524
                QChar chr = (itemText.item(b)->effects() & ScStyle_SmartHyphenVisible) ?
525
                        QChar('-') : itemText.text(b);
526
                double rightCorr = itemText.charStyle(b).font().realCharWidth(chr, chs / 10.0);
527
                if (QString("-,.`´'~").find(chr) >= 0
528
                        || chr == QChar(0x2018)
529
                        || chr == QChar(0x2019)
530
                        || chr == QChar(0x201a)
531
                        || chr == QChar(0x201b)
532
                        || chr == QChar(0x2039)
533
                        || chr == QChar(0x203a)
534
                        || chr == QChar(0x2032)
535
                        )
536
                        rightCorr *= 0.7;
537
                else if (QString(";:\"").find(chr) >= 0
538
                                 || chr == QChar(0x00ab)
539
                                 || chr == QChar(0x00bb)
540
                                 || chr == QChar(0x201c)
541
                                 || chr == QChar(0x201d)
542
                                 || chr == QChar(0x201e)
543
                                 || chr == QChar(0x201f)
544
                                 || chr == QChar(0x2013)
545
                                 || chr == QChar(0x2033)
546
                                 )
547
                        rightCorr *= 0.5;
548
                else {
549
                        rightCorr = itemText.charStyle(b).font().charWidth(chr, chs / 10.0);
550
                        rightCorr -= itemText.charStyle(b).font().charWidth(chr, chs / 10.0, QChar('.'));
551
                }
552
                return rightCorr;
553
        }
554
        return 0.0;
555
}
556
 
557
 
5362 avox 558
void PageItem_TextFrame::layout()
3614 cbradney 559
{
5732 avox 560
        if (BackBox != NULL && BackBox->invalid) {
561
//              qDebug("textframe: len=%d, going back", itemText.length());
7379 avox 562
                invalid = false;
8060 avox 563
                PageItem_TextFrame* prevInChain = dynamic_cast<PageItem_TextFrame*>(BackBox);
564
                if (!prevInChain)
8095 avox 565
                        qDebug(QString("layout(): backBox=%1").arg((ulong)BackBox));
8060 avox 566
                else
567
                        BackBox->layout();
5362 avox 568
                return;
569
        }
6370 avox 570
        else if (!invalid && OnMasterPage.isEmpty()) {
6375 avox 571
//              qDebug(QString("textframe: len=%1, invalid=%2 OnMasterPage=%3: no relayout").arg(itemText.length()).arg(invalid).arg(OnMasterPage));
5732 avox 572
                return;
573
        }
574
//      qDebug(QString("textframe(%1,%2): len=%3, start relayout at %4").arg(Xpos).arg(Ypos).arg(itemText.length()).arg(firstInFrame()));
4320 cbradney 575
        ScribusView* view = m_Doc->view();
5362 avox 576
        QPainter pf2;
577
        PageItem *nextItem;
578
        QPoint pt1, pt2;
579
        QRegion cm;
7969 avox 580
        double chs, chsd = 0;
8095 avox 581
        double oldCurY, EndX, OFs, wide, kernVal;
7313 avox 582
        QString chstr;
5362 avox 583
        ScText *hl;
6805 avox 584
        ParagraphStyle style;
8095 avox 585
        int /*ParagraphStyle::OpticalMarginType*/ opticalMargins = ParagraphStyle::OM_None;
5362 avox 586
 
587
        bool outs = false;
588
        bool fBorder = false;
589
        bool goNoRoom = false;
590
        bool goNextColumn = false;
7905 avox 591
 
592
        TabControl tabs;
593
        tabs.active    = false;     // RTab
594
        tabs.status    = TabNONE;   // TabCode
595
        tabs.charIndex = -1;        // StartRT
596
        tabs.xPos      = 0;         // RTabX
597
 
5362 avox 598
        QValueList<ParagraphStyle::TabRecord> tTabValues;
7905 avox 599
        tTabValues.clear();
600
 
5362 avox 601
        bool DropCmode = false;
602
        bool AbsHasDrop = false;
7969 avox 603
        double desc=0, asce=0, maxDY=0, desc2=0, maxDX=0;
604
        int DropLines = 0;
6370 avox 605
        double DropCapDrop = 0;
5362 avox 606
 
6144 avox 607
        itemText.clearLines();
8095 avox 608
 
609
        double lineCorr = 0;
610
        if (lineColor() != CommonStrings::None)
611
                lineCorr = m_lineWidth / 2.0;
612
 
613
        // TODO: refactor this into PageItem
614
        MarginStruct extra;
615
        extra.Top = TExtra;
616
        extra.Left = Extra;
617
        extra.Right = RExtra;
618
        extra.Bottom = BExtra;
619
 
620
        LineControl current;
621
        current.init(Width, Height, extra, lineCorr);
622
        current.initColumns(columnWidth(), ColGap);
623
        current.hyphenCount = 0;
624
 
5778 avox 625
        // dump styles
626
/*     
627
        for (int i=0; i < itemText.nrOfParagraphs(); ++i) {
628
                const ParagraphStyle& pstyle(itemText.paragraphStyle(itemText.endOfParagraph(i)));
629
                qDebug(QString("par %1:").arg(i));
630
                dumpIt(pstyle);
631
        }
632
        qDebug(QString("default:"));
633
        dumpIt(itemText.defaultStyle());
6805 avox 634
*/     
5778 avox 635
 
5362 avox 636
        pf2.begin(view->viewport());
637
        pf2.translate(Xpos, Ypos);
638
        pf2.rotate(Rot);
6144 avox 639
 
640
        setShadow();
5732 avox 641
        if ((itemText.length() != 0)) // || (NextBox != 0))
8095 avox 642
        {
5408 avox 643
                // determine layout area
5362 avox 644
                QRegion cl = availableRegion(QRegion(pf2.xForm(Clip)));
645
 
646
                if (imageFlippedH())
647
                {
648
                        pf2.translate(Width, 0);
649
                        pf2.scale(-1, 1);
650
                }
651
                if (imageFlippedV())
652
                {
653
                        pf2.translate(0, Height);
654
                        pf2.scale(1, -1);
655
                }
5408 avox 656
 
8095 avox 657
                current.nextColumn(0);
658
 
5559 avox 659
                // find start of first line
7887 avox 660
                if (firstInFrame() < itemText.length())
5362 avox 661
                {
7887 avox 662
                        hl = itemText.item(firstInFrame());
663
                        style = itemText.paragraphStyle(firstInFrame());
5721 avox 664
//                      qDebug(QString("style @0: %1 -- %2, %4/%5 char: %3").arg(style.leftMargin()).arg(style.rightMargin())
665
//                                 .arg(style.charStyle().asString()).arg(style.name()).arg(style.parent()?style.parent()->name():""));
6805 avox 666
                        if (style.hasDropCap())
3614 cbradney 667
                        {
8062 avox 668
                                if (style.lineSpacingMode() == ParagraphStyle::BaselineGridLineSpacing)
6805 avox 669
                                        chs = qRound(m_Doc->typographicSettings.valueBaseGrid  * style.dropCapLines() * 10);
5362 avox 670
                                else
6805 avox 671
                                        chs = qRound(style.lineSpacing() * style.dropCapLines() * 10);
3614 cbradney 672
                        }
6370 avox 673
                        else
5691 avox 674
                                chs = hl->fontSize();
5980 avox 675
                        desc2 = -hl->font().descent(chs / 10.0);
8095 avox 676
                        current.yPos = extra.Top + lineCorr;
5362 avox 677
                }
6370 avox 678
                else // empty itemText:
5362 avox 679
                {
6370 avox 680
                        desc2 = -itemText.defaultStyle().charStyle().font().descent(itemText.defaultStyle().charStyle().fontSize() / 10.0);
8095 avox 681
                        current.yPos = itemText.defaultStyle().lineSpacing() + extra.Top+lineCorr-desc2;
5362 avox 682
                }
8095 avox 683
                current.startLine(firstInFrame());
5362 avox 684
                outs = false;
685
                OFs = 0;
686
                MaxChars = 0;
5721 avox 687
                for (int a = firstInFrame(); a < itemText.length(); ++a)
5362 avox 688
                {
5721 avox 689
                        hl = itemText.item(a);
8060 avox 690
                        if (a > 0 && itemText.text(a-1) == SpecialChars::PARSEP)
691
                                style = itemText.paragraphStyle(a);
8095 avox 692
                        if (current.itemsInLine == 0)
8060 avox 693
                                opticalMargins = style.opticalMargins();
694
 
7887 avox 695
//                      qDebug(QString("style pos %1: %2 (%3)").arg(a).arg(style.alignment()).arg(style.parent()));
6805 avox 696
                        const CharStyle& charStyle = itemText.charStyle(a);
8060 avox 697
                        if (!charStyle.parent().isEmpty())
698
                        {
699
//                              qDebug(QString("charstyle pos %1: %2 (%3 %4 %5 %6 %7 %8 %9)").arg(a).arg(charStyle.parent())
700
//                                         .arg((uint)charStyle.parentStyle()).arg(charStyle.font().scName()).arg(charStyle.fontSize())
701
//                                         .arg(charStyle.fillColor()).arg(charStyle.strokeColor()).arg(charStyle.parentStyle()->name()).arg((uint)charStyle.parentStyle()->parentStyle()));
702
                        }                              
6144 avox 703
//                      qDebug(QString("charstyle pos %1: %2 (%3)").arg(a).arg(charStyle.asString()).arg(charStyle.fontSize()));
5721 avox 704
//                      qDebug(QString("style @%6: %1 -- %2, %4/%5 char: %3").arg(style.leftMargin()).arg(style.rightMargin())
7287 avox 705
//                                 .arg(style.charStyle().asString()).arg(style.name()).arg(style.parent())
5721 avox 706
//                                 .arg(a));
707
 
6144 avox 708
                        chstr = ExpandToken(a);
709
//                      qDebug(QString("expanded token: '%1'").arg(chstr));
710
                        if (chstr.isEmpty())
711
                                continue;
5721 avox 712
                        if (style.lineSpacingMode() == ParagraphStyle::AutomaticLineSpacing)
6805 avox 713
                                style.setLineSpacing(charStyle.font().height(charStyle.fontSize() / 10.0));
5408 avox 714
                        // find out about par gap and dropcap
5721 avox 715
                        if (a == firstInFrame())
3614 cbradney 716
                        {
5362 avox 717
                                if (BackBox != 0)
718
                                {
719
                                        nextItem = BackBox;
720
                                        while (nextItem != 0)
721
                                        {
5721 avox 722
                                                if (nextItem->frameDisplays(a-1))
5362 avox 723
                                                {
5721 avox 724
                                                        if (nextItem->itemText.text(a-1) == SpecialChars::PARSEP)
5362 avox 725
                                                        {
8095 avox 726
                                                                current.yPos += style.gapBefore();
7313 avox 727
                                                                if (chstr[0] != SpecialChars::PARSEP)
5362 avox 728
                                                                {
5721 avox 729
                                                                        DropCmode = style.hasDropCap();
5362 avox 730
                                                                        if (DropCmode)
5721 avox 731
                                                                                DropLines = style.dropCapLines();
5362 avox 732
                                                                }
733
                                                                else
734
                                                                        DropCmode = false;
735
                                                                break;
736
                                                        }
737
                                                        else
738
                                                                break;
739
                                                }
7994 avox 740
                                                nextItem = nextItem->prevInChain();
5362 avox 741
                                        }
742
                                }
743
                                else
744
                                {
7313 avox 745
                                        if (chstr[0] != SpecialChars::PARSEP)
5362 avox 746
                                        {
5721 avox 747
                                                DropCmode = style.hasDropCap();
5362 avox 748
                                                if (DropCmode)
5721 avox 749
                                                        DropLines = style.dropCapLines();
5362 avox 750
                                        }
751
                                        else
752
                                                DropCmode = false;
8095 avox 753
                                        current.yPos += style.gapBefore();
5362 avox 754
                                }
3614 cbradney 755
                        }
6370 avox 756
                        {  // local block for 'fl'
5691 avox 757
                                StyleFlag fl = hl->effects();
758
                                fl &= ~ScStyle_DropCap;
759
                                fl &= ~ScStyle_SmartHyphenVisible;
760
                                hl->setEffects(fl);
761
                        }
7887 avox 762
                        // No space at begin of line, unless at begin of par (eeks)
5412 avox 763
                        if ( //((m_Doc->docParagraphStyles[absa].alignment() == 3) || (m_Doc->docParagraphStyles[absa].alignment() == 4)) && 
7887 avox 764
                                 (a > 0 && ! isBreak(itemText.text(a-1))) &&
765
                                 ! (a > 0 && isBreakingSpace(itemText.text(a-1)) && (itemText.charStyle(a-1).effects() & ScStyle_SuppressSpace) != ScStyle_SuppressSpace) &&
8095 avox 766
                                 (current.itemsInLine == 0) && (isBreakingSpace(hl->ch[0])))
3614 cbradney 767
                        {
5691 avox 768
                                hl->setEffects(hl->effects() | ScStyle_SuppressSpace);
6144 avox 769
                                hl->glyph.xadvance = 0;
5362 avox 770
                                continue;
771
                        }
772
                        else
5691 avox 773
                                hl->setEffects(hl->effects() & ~ScStyle_SuppressSpace);
774
 
6144 avox 775
//                      qDebug(QString("textframe(%1,%2): len=%3, fontsize=%4, ascent=%5").arg(Xpos).arg(Ypos).arg(itemText.length())
776
//                                         .arg(charStyle.fontSize()).arg(charStyle.font().ascent()));                          
8095 avox 777
                        if (current.itemsInLine == 0)
5362 avox 778
                        {
5732 avox 779
                                // more about par gap and dropcaps
8095 avox 780
                                if (((a > firstInFrame()) && (itemText.text(a-1) == SpecialChars::PARSEP)) || ((a == 0) && (BackBox == 0)) && (!current.startOfCol))
3614 cbradney 781
                                {
8095 avox 782
                                        current.yPos += style.gapBefore();
6370 avox 783
                                        DropCapDrop = 0;
7313 avox 784
                                        if (chstr[0] != SpecialChars::PARSEP)
5721 avox 785
                                                DropCmode = style.hasDropCap();
5362 avox 786
                                        else
787
                                                DropCmode = false;
788
                                        if (DropCmode)
789
                                        {
5721 avox 790
                                                DropLines = style.dropCapLines();
8062 avox 791
                                                if (style.lineSpacingMode() == ParagraphStyle::BaselineGridLineSpacing)
6370 avox 792
                                                        DropCapDrop = m_Doc->typographicSettings.valueBaseGrid * (DropLines-1);
5362 avox 793
                                                else
794
                                                {
5721 avox 795
                                                        if (style.lineSpacingMode() == ParagraphStyle::FixedLineSpacing)
6805 avox 796
                                                                DropCapDrop = style.lineSpacing() * (DropLines-1);
5362 avox 797
                                                        else
6370 avox 798
                                                                DropCapDrop = charStyle.font().height(style.charStyle().fontSize() / 10.0) * (DropLines-1);
5362 avox 799
                                                }
8095 avox 800
                                                current.yPos += DropCapDrop;
5362 avox 801
                                        }
3614 cbradney 802
                                }
5362 avox 803
                        }
5408 avox 804
                        // find charsize & y pos
5362 avox 805
                        if (DropCmode)
806
                        {
5408 avox 807
                                // dropcap active?
8062 avox 808
                                if (style.lineSpacingMode() == ParagraphStyle::BaselineGridLineSpacing)
6370 avox 809
                                        DropCapDrop = m_Doc->typographicSettings.valueBaseGrid * (DropLines-1);
810
                                else
3614 cbradney 811
                                {
6370 avox 812
                                        if (style.lineSpacingMode() == ParagraphStyle::FixedLineSpacing)
6805 avox 813
                                                DropCapDrop = style.lineSpacing() * (DropLines-1);
6370 avox 814
                                        else
815
                                                DropCapDrop = charStyle.font().height(style.charStyle().fontSize() / 10.0) * (DropLines-1);
816
                                }
817
 
8062 avox 818
                                if (style.lineSpacingMode() == ParagraphStyle::BaselineGridLineSpacing)
6370 avox 819
                                {
6144 avox 820
                                        chsd = (10 * ((m_Doc->typographicSettings.valueBaseGrid * (DropLines-1)+(charStyle.font().ascent(style.charStyle().fontSize() / 10.0))) / (charStyle.font().realCharHeight(chstr[0], 1))));
821
                                        chs = (10 * ((m_Doc->typographicSettings.valueBaseGrid * (DropLines-1)+(charStyle.font().ascent(style.charStyle().fontSize() / 10.0))) / charStyle.font().realCharAscent(chstr[0], 1)));
3614 cbradney 822
                                }
5362 avox 823
                                else
3614 cbradney 824
                                {
5721 avox 825
                                        if (style.lineSpacingMode() == ParagraphStyle::FixedLineSpacing)
5362 avox 826
                                        {
6805 avox 827
                                                chsd = (10 * ((style.lineSpacing() * (DropLines-1)+(charStyle.font().ascent(style.charStyle().fontSize() / 10.0))) / (charStyle.font().realCharHeight(chstr[0], 1))));
828
                                                chs = (10 * ((style.lineSpacing() * (DropLines-1)+(charStyle.font().ascent(style.charStyle().fontSize() / 10.0))) / charStyle.font().realCharAscent(chstr[0], 1)));
5184 avox 829
                                        }
3614 cbradney 830
                                        else
831
                                        {
6144 avox 832
                                                double currasce = charStyle.font().height(style.charStyle().fontSize() / 10.0);
833
                                                chsd = (10 * ((currasce * (DropLines-1)+(charStyle.font().ascent(style.charStyle().fontSize() / 10.0))) / (charStyle.font().realCharHeight(chstr[0], 1))));
834
                                                chs = (10 * ((currasce * (DropLines-1)+(charStyle.font().ascent(style.charStyle().fontSize() / 10.0))) / charStyle.font().realCharAscent(chstr[0], 1)));
3614 cbradney 835
                                        }
5362 avox 836
                                }
5691 avox 837
                                hl->setEffects(hl->effects() | ScStyle_DropCap);
6370 avox 838
                                hl->glyph.yoffset -= DropCapDrop;
5362 avox 839
                        }
5408 avox 840
                        else // ! dropCapMode
5362 avox 841
                        {
5387 avox 842
                                if ((hl->ch == SpecialChars::OBJECT) && (hl->cembedded != 0))
5362 avox 843
                                        chs = qRound((hl->cembedded->gHeight + hl->cembedded->lineWidth()) * 10);
844
                                else
6144 avox 845
                                        chs = charStyle.fontSize();
5362 avox 846
                        }
5408 avox 847
                        // Smallcaps and such
6144 avox 848
                        hl->glyph.yadvance = 0;
5980 avox 849
                        oldCurY = layoutGlyphs(*hl, chstr, hl->glyph);
5408 avox 850
                        // find out width of char
5387 avox 851
                        if ((hl->ch == SpecialChars::OBJECT) && (hl->cembedded != 0))
5362 avox 852
                                wide = hl->cembedded->gWidth + hl->cembedded->lineWidth();
853
                        else
854
                        {
6354 avox 855
/*                              if (a+1 < itemText.length())
5362 avox 856
                                {
6144 avox 857
                                                chstr3 = itemText.text(a+1);
5408 avox 858
                                        // apply kerning
6144 avox 859
                                        wide = charStyle.font().charWidth(chstr2[0], chs / 10.0, chstr3[0]);
5362 avox 860
                                }
861
                                else
6144 avox 862
                                        wide = charStyle.font().charWidth(chstr2[0], chs / 10.0);
6354 avox 863
*/                     
864
                                wide = hl->glyph.wide();
865
                                if (a+1 < itemText.length())
866
                                {
867
                                        uint glyph2 = charStyle.font().char2CMap(itemText.text(a+1));
7356 avox 868
                                        double kern= charStyle.font().glyphKerning(hl->glyph.glyph, glyph2, chs / 10.0) * hl->glyph.scaleH;
869
                                        wide += kern;
870
                                        hl->glyph.xadvance += kern;
6354 avox 871
                                }
5362 avox 872
                        }
873
                        if (DropCmode)
874
                        {
5408 avox 875
                                // drop caps are wider...
5387 avox 876
                                if ((hl->ch == SpecialChars::OBJECT) && (hl->cembedded != 0))
5362 avox 877
                                {
878
                                        wide = hl->cembedded->gWidth + hl->cembedded->lineWidth();
8062 avox 879
                                        if (style.lineSpacingMode() == ParagraphStyle::BaselineGridLineSpacing)
5362 avox 880
                                                asce = m_Doc->typographicSettings.valueBaseGrid * DropLines;
881
                                        else
3614 cbradney 882
                                        {
5721 avox 883
                                                if (style.lineSpacingMode() == ParagraphStyle::FixedLineSpacing)
6805 avox 884
                                                        asce = style.lineSpacing() * DropLines;
5362 avox 885
                                                else
6144 avox 886
                                                        asce = charStyle.font().height(style.charStyle().fontSize() / 10.0) * DropLines;
3614 cbradney 887
                                        }
6144 avox 888
                                        hl->glyph.scaleH /= hl->glyph.scaleV;
889
                                        hl->glyph.scaleV = (asce / (hl->cembedded->gHeight + hl->cembedded->lineWidth()));
890
                                        hl->glyph.scaleH *= hl->glyph.scaleV;
5362 avox 891
                                }
892
                                else
893
                                {
7313 avox 894
                                        wide = charStyle.font().realCharWidth(chstr[0], chsd / 10.0);
895
                                        asce = charStyle.font().realCharHeight(chstr[0], chsd / 10.0);
6375 avox 896
//                                      qDebug(QString("dropcaps pre: chsd=%1 realCharHeight = %2 chstr=%3").arg(chsd).arg(asce).arg(chstr2[0]));
6144 avox 897
                                        hl->glyph.scaleH /= hl->glyph.scaleV;
8072 avox 898
                                        hl->glyph.scaleV = (asce / charStyle.font().realCharHeight(chstr[0], charStyle.fontSize() / 10.0));
6144 avox 899
                                        hl->glyph.scaleH *= hl->glyph.scaleV;
5362 avox 900
                                }
6370 avox 901
                                hl->glyph.xadvance = wide;
5362 avox 902
                                desc2 = 0;
903
                                desc = 0;
904
                        }
905
                        else
906
                        {
6144 avox 907
//                              qDebug(QString("textframe ascent/descent: fontsize=%1, ascent=%2, descent=%3")
908
//                                         .arg(charStyle.fontSize()).arg(charStyle.font().ascent()).arg(charStyle.font().descent()));                          
5408 avox 909
                                // find ascent / descent
6144 avox 910
                                double hlcsize10=charStyle.fontSize() / 10.0;
5408 avox 911
                                if ((hl->ch == SpecialChars::OBJECT) && (hl->cembedded != 0))
5362 avox 912
                                {
913
                                        desc = desc2 = 0;
914
                                }
915
                                else
916
                                {
6144 avox 917
                                        desc = desc2 = -charStyle.font().descent(hlcsize10);
5362 avox 918
                                }
6144 avox 919
                                asce = charStyle.font().ascent(hlcsize10);
6366 avox 920
//                              wide = wide * hl->glyph.scaleH;
5362 avox 921
                        }
922
                        fBorder = false;
5408 avox 923
                        // end of col reached?
8095 avox 924
//                      qDebug(QString("eocol? %1 + %2 + %3 > %4 -- asce=%5").arg(current.yPos).arg(extra.Bottom).arg(lineCorr).arg(Height).arg(asce));
925
                        if (current.isEndOfCol())
5362 avox 926
                        {
8095 avox 927
                                current.column++;
928
                                if (current.column < Cols)
5362 avox 929
                                {
5408 avox 930
                                        // start next col
8095 avox 931
                                        current.nextColumn(asce);
5721 avox 932
                                        if (((a > firstInFrame()) && (itemText.text(a-1) == SpecialChars::PARSEP))
933
                                                || ((a == firstInFrame()) && (BackBox == 0)))
3614 cbradney 934
                                        {
7313 avox 935
                                                if (chstr[0] != SpecialChars::PARSEP)
5721 avox 936
                                                        DropCmode = style.hasDropCap();
3614 cbradney 937
                                                else
5362 avox 938
                                                        DropCmode = false;
939
                                                if (DropCmode)
3614 cbradney 940
                                                {
8062 avox 941
                                                        if (style.lineSpacingMode() == ParagraphStyle::BaselineGridLineSpacing)
6144 avox 942
                                                                desc2 = -charStyle.font().descent() * m_Doc->typographicSettings.valueBaseGrid * style.dropCapLines();
3614 cbradney 943
                                                        else
6805 avox 944
                                                                desc2 = -charStyle.font().descent() * style.lineSpacing() * style.dropCapLines();
3614 cbradney 945
                                                }
5362 avox 946
                                                if (DropCmode)
5721 avox 947
                                                        DropLines = style.dropCapLines();
3614 cbradney 948
                                        }
8062 avox 949
//                                      qDebug(QString("layout: nextcol grid=%1 x %2").arg(style.lineSpacingMode() == ParagraphStyle::BaselineGridLineSpacing).arg(m_Doc->typographicSettings.valueBaseGrid));
950
                                        if (style.lineSpacingMode() == ParagraphStyle::BaselineGridLineSpacing)
3614 cbradney 951
                                        {
5362 avox 952
                                                double by = Ypos;
953
                                                if (OwnPage != -1)
954
                                                        by = Ypos - m_Doc->Pages->at(OwnPage)->yOffset();
8095 avox 955
                                                int ol1 = qRound((by + current.yPos - m_Doc->typographicSettings.offsetBaseGrid) * 10000.0);
5362 avox 956
                                                int ol2 = static_cast<int>(ol1 / m_Doc->typographicSettings.valueBaseGrid);
8095 avox 957
                                                current.yPos = ceil(  ol2 / 10000.0 ) * m_Doc->typographicSettings.valueBaseGrid + m_Doc->typographicSettings.offsetBaseGrid - by;
3614 cbradney 958
                                        }
5362 avox 959
                                }
960
                                else
961
                                {
8095 avox 962
                                        MaxChars = a;
6144 avox 963
//                                      qDebug(QString("no room A: %1").arg(a));
5362 avox 964
                                        goto NoRoom;
965
                                }
966
                        }
5408 avox 967
                        // ok, there's more room in col
8095 avox 968
                        if (current.itemsInLine == 0)
5362 avox 969
                        {
8095 avox 970
//                              qDebug(QString("newline: '%1' %2 %3").arg(a).arg(current.yPos).arg(asce));
5408 avox 971
                                // start a new line
5362 avox 972
                                double TopOffset = asce;
973
                                double BotOffset = desc2;
974
                                goNoRoom = false;
8095 avox 975
                                if (current.startOfCol)
5362 avox 976
                                {
8095 avox 977
//                                      qDebug(QString("current.startOfCol: %1 + %2 + %3").arg(asce).arg(extra.Top).arg(lineCorr));
978
                                        current.yPos = asce + extra.Top + lineCorr + 1;
5408 avox 979
//                                                      if (((a > 0) && (itemText.at(a-1)->ch == QChar(13))) || ((a == 0) && (BackBox == 0)))
8095 avox 980
//                                                              current.yPos += m_Doc->docParagraphStyles[hl->cab].gapBefore;
5362 avox 981
                                }
8062 avox 982
//                              qDebug(QString("layout: nextline grid=%1 x %2").arg(style.lineSpacingMode() == ParagraphStyle::BaselineGridLineSpacing).arg(m_Doc->typographicSettings.valueBaseGrid));
983
                                if (style.lineSpacingMode() == ParagraphStyle::BaselineGridLineSpacing)
5362 avox 984
                                {
985
                                        double by = Ypos;
986
                                        if (OwnPage != -1)
987
                                                by = Ypos - m_Doc->Pages->at(OwnPage)->yOffset();
8095 avox 988
                                        int ol1 = qRound((by + current.yPos - m_Doc->typographicSettings.offsetBaseGrid) * 10000.0);
5362 avox 989
                                        int ol2 = static_cast<int>(ol1 / m_Doc->typographicSettings.valueBaseGrid);
6144 avox 990
//                                      qDebug(QString("useBaselIneGrid: %1 * %2 + %3 - %4").arg(ol2 / 10000.0).arg(m_Doc->typographicSettings.valueBaseGrid).arg(m_Doc->typographicSettings.offsetBaseGrid).arg(by));
8095 avox 991
                                        current.yPos = ceil(  ol2 / 10000.0 ) * m_Doc->typographicSettings.valueBaseGrid + m_Doc->typographicSettings.offsetBaseGrid - by;
5362 avox 992
                                }
8095 avox 993
                                if (current.yPos-TopOffset < 0.0)
994
                                        current.yPos = TopOffset+1;
5408 avox 995
                                // find linelength:
8095 avox 996
                                pt1 = QPoint(static_cast<int>(ceil(current.xPos)), static_cast<int>(current.yPos+BotOffset));
997
                                pt2 = QPoint(static_cast<int>(ceil(current.xPos)), static_cast<int>(ceil(current.yPos-TopOffset)));
5408 avox 998
                                // increase pt1/pt2 until i-beam reaches end of line
8095 avox 999
//                              qDebug(QString("linestart: %1 + %2 + %3 < %4").arg(current.xPos).arg(wide).arg(style.rightMargin()).arg(current.colRight));
1000
                                double leftIndent = 0;
1001
                                while (!cl.contains(pf2.xForm(pt1)) || !cl.contains(pf2.xForm(pt2)) || current.isEndOfLine(wide + leftIndent + style.rightMargin()))
5362 avox 1002
                                {
1003
                                        fBorder = true;
8095 avox 1004
                                        current.xPos++;
1005
                                        if (current.isEndOfLine(wide + leftIndent + style.rightMargin()))
3614 cbradney 1006
                                        {
8095 avox 1007
                                                qDebug(QString("eocol %5? %1 + %2 + %3 + %4").arg(current.yPos).arg(current.startOfCol).arg(style.lineSpacingMode() == ParagraphStyle::BaselineGridLineSpacing).arg(style.lineSpacing()).arg(current.column));
5408 avox 1008
                                                // new line
5362 avox 1009
                                                fBorder = false;
8095 avox 1010
                                                current.xPos = current.colLeft;
1011
 
1012
                                                leftIndent = style.leftMargin();
1013
                                                if (a > 0 && itemText.text(a-1) == SpecialChars::PARSEP)
1014
                                                        leftIndent += style.firstIndent();
1015
 
1016
                                                if (current.startOfCol)
3614 cbradney 1017
                                                {
8095 avox 1018
                                                        current.yPos++;
3614 cbradney 1019
                                                }
5362 avox 1020
                                                else
3614 cbradney 1021
                                                {
8095 avox 1022
                                                        current.yPos += style.lineSpacing();
3614 cbradney 1023
                                                }
8062 avox 1024
//                                              qDebug(QString("layout: next lower line grid=%1 x %2").arg(style.lineSpacingMode() == ParagraphStyle::BaselineGridLineSpacing).arg(m_Doc->typographicSettings.valueBaseGrid));
1025
                                                if (style.lineSpacingMode() == ParagraphStyle::BaselineGridLineSpacing)
3614 cbradney 1026
                                                {
5362 avox 1027
                                                        double by = Ypos;
1028
                                                        if (OwnPage != -1)
1029
                                                                by = Ypos - m_Doc->Pages->at(OwnPage)->yOffset();
8095 avox 1030
                                                        int ol1 = qRound((by + current.yPos - m_Doc->typographicSettings.offsetBaseGrid) * 10000.0);
5362 avox 1031
                                                        int ol2 = static_cast<int>(ol1 / m_Doc->typographicSettings.valueBaseGrid);
8095 avox 1032
                                                        current.yPos = ceil(  ol2 / 10000.0 ) * m_Doc->typographicSettings.valueBaseGrid + m_Doc->typographicSettings.offsetBaseGrid - by;
5362 avox 1033
                                                }
8095 avox 1034
                                                if (current.isEndOfCol())
5362 avox 1035
                                                {
1036
                                                        fBorder = false;
8095 avox 1037
                                                        current.column++;
1038
                                                        if (current.column < Cols)
3614 cbradney 1039
                                                        {
8095 avox 1040
                                                                current.nextColumn(asce);
5721 avox 1041
                                                                if (((a > firstInFrame()) && (itemText.text(a-1) == SpecialChars::PARSEP)) || ((a == firstInFrame()) && (BackBox == 0)))
3614 cbradney 1042
                                                                {
7313 avox 1043
                                                                        if (chstr[0] != SpecialChars::PARSEP)
5721 avox 1044
                                                                                DropCmode = style.hasDropCap();
3614 cbradney 1045
                                                                        else
5362 avox 1046
                                                                                DropCmode = false;
1047
                                                                        if (DropCmode)
1048
                                                                        {
8062 avox 1049
                                                                                if (style.lineSpacingMode() == ParagraphStyle::BaselineGridLineSpacing)
6144 avox 1050
                                                                                        desc2 = -charStyle.font().descent() * m_Doc->typographicSettings.valueBaseGrid * style.dropCapLines();
5362 avox 1051
                                                                                else
6805 avox 1052
                                                                                        desc2 = -charStyle.font().descent() * style.lineSpacing() * style.dropCapLines();
5362 avox 1053
                                                                        }
1054
                                                                        if (DropCmode)
5721 avox 1055
                                                                                DropLines = style.dropCapLines();
3614 cbradney 1056
                                                                }
8062 avox 1057
//                                                              qDebug(QString("layout: nextcol2 grid=%1 x %2").arg(style.lineSpacingMode() == ParagraphStyle::BaselineGridLineSpacing).arg(m_Doc->typographicSettings.valueBaseGrid));
1058
                                                                if (style.lineSpacingMode() == ParagraphStyle::BaselineGridLineSpacing)
3614 cbradney 1059
                                                                {
5362 avox 1060
                                                                        double by = Ypos;
1061
                                                                        if (OwnPage != -1)
1062
                                                                                by = Ypos - m_Doc->Pages->at(OwnPage)->yOffset();
8095 avox 1063
                                                                        int ol1 = qRound((by + current.yPos - m_Doc->typographicSettings.offsetBaseGrid) * 10000.0);
5362 avox 1064
                                                                        int ol2 = static_cast<int>(ol1 / m_Doc->typographicSettings.valueBaseGrid);
8095 avox 1065
                                                                        current.yPos = ceil(  ol2 / 10000.0 ) * m_Doc->typographicSettings.valueBaseGrid + m_Doc->typographicSettings.offsetBaseGrid - by;
3614 cbradney 1066
                                                                }
1067
                                                        }
1068
                                                        else
5362 avox 1069
                                                        {
8095 avox 1070
                                                                MaxChars = a;
6144 avox 1071
//                                                              qDebug(QString("no room B: %1").arg(a));
5362 avox 1072
                                                                goto NoRoom;
1073
                                                        }
3614 cbradney 1074
                                                }
5362 avox 1075
                                        }
8095 avox 1076
                                        pt1 = QPoint(static_cast<int>(ceil(current.xPos)), static_cast<int>(current.yPos+BotOffset));
1077
                                        pt2 = QPoint(static_cast<int>(ceil(current.xPos)), static_cast<int>(ceil(current.yPos-TopOffset)));
5362 avox 1078
                                }
5408 avox 1079
 
5362 avox 1080
                                if (((fBorder)) && (!AbsHasDrop))
8095 avox 1081
                                        current.xPos += extra.Left;
5408 avox 1082
                                // indent first line of par
5362 avox 1083
                                if (a > 0)
1084
                                {
5721 avox 1085
                                        if (itemText.text(a-1) == SpecialChars::PARSEP)
8095 avox 1086
                                                current.xPos += style.firstIndent();
5362 avox 1087
                                }
1088
                                else
1089
                                {
1090
                                        if (BackBox == 0)
8095 avox 1091
                                                current.xPos += style.firstIndent();
5362 avox 1092
                                        else
1093
                                        {
5721 avox 1094
                                                if (BackBox->frameDisplays(firstInFrame()-1))
3614 cbradney 1095
                                                {
5721 avox 1096
                                                        if (BackBox->itemText.text(BackBox->lastInFrame()) == SpecialChars::PARSEP)
8095 avox 1097
                                                                current.xPos += style.firstIndent();
3614 cbradney 1098
                                                }
5362 avox 1099
                                                else
8095 avox 1100
                                                        current.xPos += style.firstIndent();
3614 cbradney 1101
                                        }
1102
                                }
5408 avox 1103
                                // add left margin
5362 avox 1104
                                if (!AbsHasDrop)
8095 avox 1105
                                        current.xPos += style.leftMargin();
1106
                                if (opticalMargins & ParagraphStyle::OM_LeftHangingPunct) {
1107
                                        current.xPos += opticalLeftMargin(itemText, current.line);
5390 avox 1108
                                }
8095 avox 1109
                                current.line.x = current.xPos;
1110
                                current.line.y = current.yPos;
5362 avox 1111
                                fBorder = false;
1112
                        }
6144 avox 1113
                        else {
1114
//                              qDebug(QString("cont.' line: '%1'").arg(a));
1115
                        }
5408 avox 1116
                        // right tab stuff
7905 avox 1117
                        if (tabs.active)
5362 avox 1118
                        {
7905 avox 1119
                                if (((hl->ch == ".") && (tabs.status == TabPOINT)) || ((hl->ch == ",") && (tabs.status == TabCOMMA)) || (hl->ch == SpecialChars::TAB))
5362 avox 1120
                                {
7905 avox 1121
                                        tabs.active = false;
1122
                                        tabs.status = TabNONE;
3614 cbradney 1123
                                }
1124
                        }
5408 avox 1125
                        // tab positioning
5387 avox 1126
                        if (hl->ch == SpecialChars::TAB)
3614 cbradney 1127
                        {
5362 avox 1128
                                wide = 1;
7905 avox 1129
                                if (tabs.active)
1130
                                        tabs.active = false;
1131
                                else // ???
3614 cbradney 1132
                                {
8095 avox 1133
                                        tabs.xPos = current.xPos;
5721 avox 1134
                                        tTabValues = style.tabValues();
5362 avox 1135
                                        if (tTabValues.isEmpty())
3614 cbradney 1136
                                        {
8095 avox 1137
                                                if ((current.xPos - current.colLeft) != 0)
3614 cbradney 1138
                                                {
8095 avox 1139
                                                        if (current.xPos == current.colLeft + ceil((current.xPos-current.colLeft) / m_Doc->toolSettings.dTabWidth) * m_Doc->toolSettings.dTabWidth)
1140
                                                                current.xPos += m_Doc->toolSettings.dTabWidth;
5362 avox 1141
                                                        else
8095 avox 1142
                                                                current.xPos = current.colLeft + ceil((current.xPos-current.colLeft) / m_Doc->toolSettings.dTabWidth) * m_Doc->toolSettings.dTabWidth;
3614 cbradney 1143
                                                }
5362 avox 1144
                                                else
8095 avox 1145
                                                        current.xPos = current.colLeft + m_Doc->toolSettings.dTabWidth;
7905 avox 1146
                                                tabs.status = TabNONE;
1147
                                                tabs.active = false;
3614 cbradney 1148
                                        }
5362 avox 1149
                                        else
1150
                                        {
8095 avox 1151
                                                double tCurX = current.xPos - current.colLeft;
5362 avox 1152
                                                double oCurX = tCurX + wide;
1153
                                                for (int yg = static_cast<int>(tTabValues.count()-1); yg > -1; yg--)
1154
                                                {
1155
                                                        if (oCurX < tTabValues[yg].tabPosition)
1156
                                                        {
7905 avox 1157
                                                                tabs.status = static_cast<int>(tTabValues[yg].tabType);
5362 avox 1158
                                                                tCurX = tTabValues[yg].tabPosition;
7905 avox 1159
                                                                tabs.fillChar    = tTabValues[yg].tabFillChar;
5362 avox 1160
                                                        }
1161
                                                }
7905 avox 1162
                                                tabs.active = (tabs.status != TabLEFT);
5362 avox 1163
                                                if (tCurX == oCurX-wide)
8095 avox 1164
                                                        current.xPos = current.colLeft + ceil((current.xPos-current.colLeft) / m_Doc->toolSettings.dTabWidth) * m_Doc->toolSettings.dTabWidth;
5362 avox 1165
                                                else
8095 avox 1166
                                                        current.xPos = current.colLeft + tCurX;
7905 avox 1167
 
1168
                                                // remember fill char
7994 avox 1169
//                                              qDebug(QString("tab: %1 '%2'").arg(tCurX).arg(tabs.fillChar));
7905 avox 1170
                                                if (!tabs.fillChar.isNull()) {
1171
                                                        hl->glyph.grow();
1172
                                                        GlyphLayout * tglyph = hl->glyph.more;
1173
                                                        tglyph->glyph = charStyle.font().char2CMap(tabs.fillChar);
1174
                                                        tglyph->yoffset = hl->glyph.yoffset;
1175
                                                        tglyph->scaleV = tglyph->scaleH = chs / charStyle.fontSize();
1176
                                                        tglyph->xadvance = 0;
1177
                                                }
5362 avox 1178
                                        }
8095 avox 1179
                                        hl->glyph.xadvance = current.xPos - tabs.xPos;
1180
//                                      wide = current.xPos - RTabX;
7905 avox 1181
                                        tabs.charIndex = a;
3614 cbradney 1182
                                }
5362 avox 1183
                        }
1184
 
5408 avox 1185
                        // remember y pos
8095 avox 1186
//                      hl->glyph.yoffset = current.yPos + oldCurY;
6370 avox 1187
//                      hl->glyph.yoffset = 0;
5362 avox 1188
                        if (DropCmode)
7313 avox 1189
                                hl->glyph.yoffset -= charStyle.font().realCharHeight(chstr[0], chsd / 10.0) - charStyle.font().realCharAscent(chstr[0], chsd / 10.0);
5408 avox 1190
                        // find tracking
8095 avox 1191
                        if (current.itemsInLine == 0)
5362 avox 1192
                        {
5721 avox 1193
                                itemText.item(a)->setEffects(itemText.item(a)->effects() | ScStyle_StartOfLine);
5362 avox 1194
                                kernVal = 0;
1195
                        }
1196
                        else
1197
                        {
7188 avox 1198
                                kernVal = 0; // chs * charStyle.tracking() / 10000.0;
5721 avox 1199
                                itemText.item(a)->setEffects(itemText.item(a)->effects() & ~ScStyle_StartOfLine);
5362 avox 1200
                        }
8095 avox 1201
 
1202
                        // remember possible break
1203
                        if ( (isBreakingSpace(hl->ch[0]) || hl->ch == SpecialChars::TAB) && !outs)
1204
                        {
1205
                                if ( a == firstInFrame() || !isBreakingSpace(itemText.text(a-1)) )
1206
                                {
1207
                                        current.rememberBreak(a, current.xPos);
1208
                                }
1209
                        }
1210
 
1211
 
5408 avox 1212
                        // remember x pos
7905 avox 1213
                        if (!tabs.active) // normal case
5362 avox 1214
                        {
8095 avox 1215
//                              hl->glyph.xoffset = QMAX(current.xPos+kernVal, current.colLeft);
1216
                                //hl->glyph.xoffset = current.xPos+kernVal; // needed for left optical margin
1217
                                current.xPos += wide+kernVal;
1218
//                              current.xPos = QMAX(current.xPos, current.colLeft);
5362 avox 1219
                        }
7905 avox 1220
                        else if (tabs.active && tabs.status == TabCENTER)       // center tab
5362 avox 1221
                        {
8095 avox 1222
                                current.xPos += (wide+kernVal) / 2;
1223
                                current.xPos = QMAX(current.xPos, current.colLeft);
5362 avox 1224
                        }
7905 avox 1225
                        else // other tabs.active                       
5362 avox 1226
                        {
8095 avox 1227
                                current.xPos = QMAX(current.xPos, current.colLeft);
1228
                                //hl->glyph.xoffset = current.xPos;
5362 avox 1229
                        }
7231 avox 1230
 
8095 avox 1231
 
5408 avox 1232
                        // hyphenation
8095 avox 1233
                        if (((hl->effects() & ScStyle_HyphenationPossible) || (hl->ch == "-") || hl->ch[0] == SpecialChars::SHYPHEN) && (!outs) && !itemText.text(a-1).isSpace() )
1234
                        {
1235
                                double breakPos = current.xPos;
1236
                                if (hl->ch != "-")
1237
                                {
1238
                                        breakPos += charStyle.font().charWidth('-', charStyle.fontSize() / 10.0) * (charStyle.scaleH() / 1000.0);
1239
                                }
1240
 
1241
                                double rightHang = 0;
1242
                                if (opticalMargins & ParagraphStyle::OM_RightHangingPunct) {
1243
                                        rightHang = 0.7 * charStyle.font().realCharWidth('-', (charStyle.fontSize() / 10.0) * (charStyle.scaleH() / 1000.0));
1244
                                }
1245
 
1246
                                if (breakPos - 0 < current.colRight - style.rightMargin())
1247
                                {
1248
                                        if ((current.hyphenCount < m_Doc->HyCount) || (m_Doc->HyCount == 0) || hl->ch[0] == SpecialChars::SHYPHEN)
1249
                                        {
1250
                                                current.rememberBreak(a, breakPos);
1251
                                        }
1252
                                }
1253
                        }
1254
 
1255
                        ++current.itemsInLine;
1256
 
1257
/*                                             
7346 avox 1258
                        //FIXME: asce / desc set correctly?
8095 avox 1259
                        if ((((hl->effects() & ScStyle_HyphenationPossible) || hl->ch == "-") && (current.hyphenCount < m_Doc->HyCount || m_Doc->HyCount == 0))  || hl->ch[0] == SpecialChars::SHYPHEN)
5362 avox 1260
                        {
6934 avox 1261
                                if (hl->effects() & ScStyle_HyphenationPossible || hl->ch[0] == SpecialChars::SHYPHEN)
3614 cbradney 1262
                                {
8095 avox 1263
                                        pt1 = QPoint(qRound(ceil(current.xPos+extra.Right+ charStyle.font().charWidth('-', charStyle.fontSize() / 10.0) * (charStyle.scaleH() / 1000.0))), qRound(current.yPos+desc));
1264
                                        pt2 = QPoint(qRound(ceil(current.xPos+extra.Right+ charStyle.font().charWidth('-', charStyle.fontSize() / 10.0) * (charStyle.scaleH() / 1000.0))), qRound(ceil(current.yPos-asce)));
3614 cbradney 1265
                                }
5362 avox 1266
                                else
3614 cbradney 1267
                                {
8095 avox 1268
                                        pt1 = QPoint(qRound(ceil(current.xPos+extra.Right)), qRound(current.yPos+desc));
1269
                                        pt2 = QPoint(qRound(ceil(current.xPos+extra.Right)), qRound(ceil(current.yPos-asce)));
3614 cbradney 1270
                                }
5362 avox 1271
                        }
8095 avox 1272
                        else */
5362 avox 1273
                        {
8095 avox 1274
                                pt1 = QPoint(qRound(ceil(current.xPos+extra.Right)), qRound(current.yPos+desc));
1275
                                pt2 = QPoint(qRound(ceil(current.xPos+extra.Right)), qRound(ceil(current.yPos-asce)));
5362 avox 1276
                        }
5408 avox 1277
 
1278
                        // test if end of line reached
8095 avox 1279
                        if ((!cl.contains(pf2.xForm(pt1))) || (!cl.contains(pf2.xForm(pt2))) || (current.isEndOfLine(style.rightMargin())))
5362 avox 1280
                                outs = true;
8095 avox 1281
                        if (current.isEndOfCol())
5362 avox 1282
                                outs = true;
7905 avox 1283
                        if ((hl->ch == SpecialChars::FRAMEBREAK) && (a < itemText.length()-1))
5362 avox 1284
                                goNoRoom = true;
7905 avox 1285
                        if ((hl->ch == SpecialChars::COLBREAK) && (Cols > 1))
5362 avox 1286
                                goNextColumn = true;
6144 avox 1287
 
7905 avox 1288
                        if (tabs.active)
5362 avox 1289
                        {
1290
                                double cen = 1;
7905 avox 1291
                                if (tabs.status == TabCENTER)
5362 avox 1292
                                        cen = 2;
7231 avox 1293
 
7905 avox 1294
                                double newTabAdvance = itemText.item(tabs.charIndex)->glyph.xadvance - (wide+kernVal) / cen;
7231 avox 1295
 
1296
                                if (newTabAdvance >= 0) {
7905 avox 1297
                                        itemText.item(tabs.charIndex)->glyph.xadvance = newTabAdvance;
7231 avox 1298
                                }
1299
                                else {
7905 avox 1300
                                        tabs.active = false;
1301
                                        tabs.status = TabNONE;
7231 avox 1302
                                }
5362 avox 1303
                        }
7313 avox 1304
//                      BuPos++;
5362 avox 1305
                        if (DropCmode)
1306
                        {
1307
                                DropCmode = false;
1308
                                AbsHasDrop = true;
8095 avox 1309
                                maxDY = current.yPos;
1310
                                current.xPos += style.dropCapOffset();
7287 avox 1311
                                hl->glyph.xadvance += style.dropCapOffset();
8095 avox 1312
//                              qDebug(QString("dropcapoffset: %1 -> %2").arg(current.xPos-style.dropCapOffset()).arg(current.xPos));
1313
                                current.xPos = QMAX(current.xPos, current.colLeft);
1314
                                maxDX = current.xPos;
5362 avox 1315
                                QPointArray tcli(4);
8062 avox 1316
                                if (style.lineSpacingMode() == ParagraphStyle::BaselineGridLineSpacing)
5362 avox 1317
                                {
8095 avox 1318
                                        current.yPos -= m_Doc->typographicSettings.valueBaseGrid * (DropLines-1);
5362 avox 1319
                                        double by = Ypos;
1320
                                        if (OwnPage != -1)
1321
                                                by = Ypos - m_Doc->Pages->at(OwnPage)->yOffset();
8095 avox 1322
                                        int ol1 = qRound((by + current.yPos - m_Doc->typographicSettings.offsetBaseGrid) * 10000.0);
5362 avox 1323
                                        int ol2 = static_cast<int>(ol1 / m_Doc->typographicSettings.valueBaseGrid);
8095 avox 1324
                                        current.yPos = ceil(  ol2 / 10000.0 ) * m_Doc->typographicSettings.valueBaseGrid + m_Doc->typographicSettings.offsetBaseGrid - by;
1325
                                        //FIXME: use current.colLeft instead of xOffset?
5691 avox 1326
                                        tcli.setPoint(0, QPoint(qRound(hl->glyph.xoffset), qRound(maxDY-DropLines*m_Doc->typographicSettings.valueBaseGrid)));
5362 avox 1327
                                        tcli.setPoint(1, QPoint(qRound(maxDX), qRound(maxDY-DropLines*m_Doc->typographicSettings.valueBaseGrid)));
1328
                                }
1329
                                else
1330
                                {
5721 avox 1331
                                        if (style.lineSpacingMode() == ParagraphStyle::FixedLineSpacing)
3614 cbradney 1332
                                        {
8095 avox 1333
                                                current.yPos -= style.lineSpacing() * (DropLines-1);
6805 avox 1334
                                                tcli.setPoint(0, QPoint(qRound(hl->glyph.xoffset), qRound(maxDY - DropLines * style.lineSpacing())));
1335
                                                tcli.setPoint(1, QPoint(qRound(maxDX), qRound(maxDY-DropLines*style.lineSpacing())));
5362 avox 1336
                                        }
1337
                                        else
1338
                                        {
6144 avox 1339
                                                double currasce = charStyle.font().height(style.charStyle().fontSize() / 10.0);
8095 avox 1340
                                                current.yPos -= currasce * (DropLines-1);
5691 avox 1341
                                                tcli.setPoint(0, QPoint(qRound(hl->glyph.xoffset), qRound(maxDY-DropLines*currasce)));
5362 avox 1342
                                                tcli.setPoint(1, QPoint(qRound(maxDX), qRound(maxDY-DropLines*currasce)));
1343
                                        }
1344
                                }
1345
                                tcli.setPoint(2, QPoint(qRound(maxDX), qRound(maxDY)));
5691 avox 1346
                                tcli.setPoint(3, QPoint(qRound(hl->glyph.xoffset), qRound(maxDY)));
5362 avox 1347
                                cm = QRegion(pf2.xForm(tcli));
1348
                                cl = cl.subtract(cm);
8095 avox 1349
//                              current.yPos = maxDY;
5362 avox 1350
                        }
5408 avox 1351
                        // end of line
7887 avox 1352
                        if ( isBreak(hl->ch[0], Cols > 1) || (outs))
5362 avox 1353
                        {
7905 avox 1354
                                tabs.active = false;
1355
                                tabs.status = TabNONE;
7887 avox 1356
                                if (isBreak(hl->ch[0], Cols > 1))
5362 avox 1357
                                {
8095 avox 1358
                                        // find end of line
1359
                                        current.breakLine(itemText, a);
1360
                                        EndX = current.endOfLine(cl, pf2, asce, desc, style.rightMargin());
1361
                                        current.finishLine(EndX);
1362
 
5721 avox 1363
                                        if (style.alignment() != 0)
5362 avox 1364
                                        {
8095 avox 1365
                                                if (opticalMargins & ParagraphStyle::OM_RightHangingPunct)
1366
                                                        current.line.width += opticalRightMargin(itemText, current.line);
1367
 
1368
                                                OFs = 0;
5721 avox 1369
                                                if (style.alignment() == 2)
8095 avox 1370
                                                        OFs = current.line.width - current.line.naturalWidth;
5721 avox 1371
                                                if (style.alignment() == 1)
8095 avox 1372
                                                        OFs = (current.line.width - current.line.naturalWidth) / 2;
5721 avox 1373
                                                if (style.alignment() == 3)
5362 avox 1374
                                                        OFs = 0;
8095 avox 1375
 
7037 avox 1376
                                                if (style.alignment() == 4
1377
                                                        || (style.alignment() == 3
7287 avox 1378
                                                                &&  (hl->ch == SpecialChars::LINEBREAK ||
1379
                                                                         hl->ch == SpecialChars::FRAMEBREAK ||
1380
                                                                         hl->ch == SpecialChars::COLBREAK)
8095 avox 1381
                                                                &&  !itemText.text(current.line.lastItem - 1).isSpace()))
5362 avox 1382
                                                {
8095 avox 1383
                                                        justifyLine(itemText, current.line);
3614 cbradney 1384
                                                }
1385
                                                else
1386
                                                {
5408 avox 1387
                                                        // simple offset
8095 avox 1388
                                                        indentLine(current.line, OFs);
3614 cbradney 1389
                                                }
8095 avox 1390
                                                current.xPos = current.line.x + current.line.width;
3614 cbradney 1391
                                        }
5362 avox 1392
                                }
5408 avox 1393
                                else // outs -- last char went outside the columns
5362 avox 1394
                                {
8095 avox 1395
                                        if (current.breakIndex >= 0)            // Hier koenen auch andere Trennungen eingebaut werden
3614 cbradney 1396
                                        {
5408 avox 1397
                                                // go back to last break position
8095 avox 1398
//                                              qDebug(QString("new break pos a=%1 BuPos=%2 current.breakIndex=%3").arg(a).arg(BuPos).arg(current.breakIndex));
1399
                                                a = current.breakIndex;
5980 avox 1400
                                                assert( a >= 0 );
1401
                                                assert( a < itemText.length() );
5721 avox 1402
                                                hl = itemText.item(a);
6805 avox 1403
                                                style = itemText.paragraphStyle(a);
8095 avox 1404
                                                current.itemsInLine = a - current.line.firstItem + 1;
7887 avox 1405
//                                              qDebug(QString("style outs pos %1: %2 (%3)").arg(a).arg(style.alignment()).arg(style.parent()));
6805 avox 1406
//                                              qDebug(QString("style <@%6: %1 -- %2, %4/%5 char: %3").arg(style.leftMargin()).arg(style.rightMargin())
1407
//                                                         .arg(style.charStyle().asString()).arg(style.name()).arg(style.parent()?style.parent()->name():"")
5721 avox 1408
//                                                         .arg(a));
7356 avox 1409
 
1410
                                                if (hl->ch[0] == ' ') {
1411
                                                        hl->setEffects(hl->effects() | ScStyle_SuppressSpace);
1412
                                                        hl->glyph.xadvance = 0;
1413
                                                }
6144 avox 1414
 
8095 avox 1415
                                                EndX = current.endOfLine(cl, pf2, asce, desc, style.rightMargin());
1416
                                                current.finishLine(EndX);
1417
 
1418
//???                                           current.breakXPos = current.line.x;
1419
//???                                           for (int j=current.line.firstItem; j <= a; ++j)
1420
//???                                                   current.breakXPos += itemText.item(j)->glyph.wide();
1421
 
6998 avox 1422
                                                if ((hl->effects() & ScStyle_HyphenationPossible) || hl->ch[0] == SpecialChars::SHYPHEN)
3614 cbradney 1423
                                                {
5362 avox 1424
                                                        // insert hyphen
8095 avox 1425
                                                        current.hyphenCount++;
5691 avox 1426
                                                        hl->setEffects(hl->effects() | ScStyle_SmartHyphenVisible);
8095 avox 1427
                                                        hl->glyph.grow();
6144 avox 1428
                                                        hl->glyph.more->glyph = charStyle.font().char2CMap(QChar('-'));
1429
                                                        hl->glyph.more->xadvance = charStyle.font().charWidth('-', itemText.charStyle(a).fontSize() / 10.0) * (itemText.charStyle(a).scaleH() / 1000.0);
8095 avox 1430
//                                                      current.breakIndex += 2;
1431
//???                                                   current.breakXPos += hl->glyph.more->xadvance;
5362 avox 1432
                                                }
5408 avox 1433
                                                else
5362 avox 1434
                                                {
8095 avox 1435
                                                        if (hl->ch[0] != '-')
1436
                                                                current.hyphenCount = 0;
5691 avox 1437
                                                        hl->setEffects(hl->effects() & ~ScStyle_SmartHyphenVisible);
8095 avox 1438
                                                        hl->glyph.shrink();
1439
//                                                      current.breakIndex += 1;
5362 avox 1440
                                                }
8095 avox 1441
 
5408 avox 1442
                                                // Justification
6805 avox 1443
                                                if (style.alignment() != 0)
5362 avox 1444
                                                {
8095 avox 1445
                                                        if (opticalMargins & ParagraphStyle::OM_RightHangingPunct)
1446
                                                                current.line.width += opticalRightMargin(itemText, current.line);
5408 avox 1447
 
8095 avox 1448
                                                        OFs = 0;
6805 avox 1449
                                                        if (style.alignment() == 2)
8095 avox 1450
                                                                OFs = current.line.width - current.line.naturalWidth;
6805 avox 1451
                                                        if (style.alignment() == 1)
8095 avox 1452
                                                                OFs = (current.line.width - current.line.naturalWidth) / 2;
1453
 
6805 avox 1454
                                                        if ((style.alignment() == 3)
1455
                                                                || (style.alignment() == 4))
5362 avox 1456
                                                        {
8095 avox 1457
                                                                justifyLine(itemText, current.line);
3614 cbradney 1458
                                                        }
5362 avox 1459
                                                        else
1460
                                                        {
8095 avox 1461
                                                                indentLine(current.line, OFs);
5362 avox 1462
                                                        }
5408 avox 1463
//                                                      qDebug(QString("line: endx=%1 lastchar=%2").arg(EndX).arg(LiList.at(BuPos-1)->xco + LiList.at(BuPos-1)->wide));
8095 avox 1464
                                                        current.xPos = current.line.x + current.line.width;
3614 cbradney 1465
                                                }
1466
                                        }
8095 avox 1467
                                        else  // no break position
3614 cbradney 1468
                                        {
8095 avox 1469
                                                if (a > current.line.firstItem)
1470
                                                {
1471
                                                        --a;
1472
                                                        --current.itemsInLine;
1473
                                                        hl = itemText.item(a);
1474
                                                        style = itemText.paragraphStyle(a);
1475
                                                }
1476
                                                current.breakLine(itemText, a);
7887 avox 1477
//                                              qDebug(QString("style no break pos %1: %2 (%3)").arg(a).arg(style.alignment()).arg(style.parent()));
6805 avox 1478
//                                              qDebug(QString("style nb @%6: %1 -- %2, %4/%5 char: %3").arg(style.leftMargin()).arg(style.rightMargin())
7188 avox 1479
//                                                         .arg(style.charStyle().asString()).arg(style.name()).arg(style.parent())
5778 avox 1480
//                                                         .arg(a));
8095 avox 1481
                                                EndX = current.endOfLine(cl, pf2, asce, desc, style.rightMargin());
1482
                                                current.finishLine(EndX);
1483
                                                qDebug(QString("no break pos: %1-%2 @ %3 wid %4 nat %5 endX %6")
1484
                                                           .arg(current.line.firstItem).arg(current.line.firstItem)
1485
                                                           .arg(current.line.x).arg(current.line.width).arg(current.line.naturalWidth).arg(EndX));
5362 avox 1486
                                        }
1487
                                }
7887 avox 1488
                                if ( outs || isBreak(hl->ch[0], (Cols > 1)) )
5362 avox 1489
                                {
8095 avox 1490
                                        if (outs && current.isEndOfLine(hl->glyph.wide() + style.rightMargin()))
5362 avox 1491
                                        {
8095 avox 1492
                                                if (( hl->ch[0] == SpecialChars::PARSEP || hl->ch[0] == SpecialChars::LINEBREAK)
5362 avox 1493
                                                        && AbsHasDrop)
3614 cbradney 1494
                                                {
5362 avox 1495
                                                        AbsHasDrop = false;
8095 avox 1496
                                                        if (current.yPos < maxDY)
1497
                                                                current.yPos = maxDY;
3614 cbradney 1498
                                                }
5362 avox 1499
                                                bool fromOut = true;
8095 avox 1500
                                                double BotOffset = desc+extra.Bottom+lineCorr;
1501
//                                              pt1 = QPoint(qRound(current.xPos+extra.Right), static_cast<int>(current.yPos+BotOffset));
1502
//                                              pt2 = QPoint(qRound(current.xPos+extra.Right), static_cast<int>(ceil(current.yPos-asce)));
1503
                                                while (!current.isEndOfLine(style.rightMargin()))
3614 cbradney 1504
                                                {
8095 avox 1505
                                                        current.xPos++;
1506
                                                        if (current.isEndOfLine(style.rightMargin()))
3614 cbradney 1507
                                                        {
5362 avox 1508
                                                                fromOut = false;
8062 avox 1509
//                                                              qDebug(QString("layout: next lower2 grid=%1 x %2").arg(style.lineSpacingMode() == ParagraphStyle::BaselineGridLineSpacing).arg(m_Doc->typographicSettings.valueBaseGrid));
1510
                                                                if (style.lineSpacingMode() == ParagraphStyle::BaselineGridLineSpacing)
8095 avox 1511
                                                                        current.yPos += m_Doc->typographicSettings.valueBaseGrid;
5362 avox 1512
                                                                else
8095 avox 1513
                                                                        current.yPos += style.lineSpacing();
1514
                                                                if (current.isEndOfCol(desc) && (current.column+1 == Cols))
5362 avox 1515
                                                                {
1516
                                                                        goNoRoom = true;
6375 avox 1517
//                                                                      qDebug(QString("go no room 1: %1").arg(a));
5362 avox 1518
                                                                        break;
1519
                                                                }
1520
                                                                if (AbsHasDrop)
1521
                                                                {
8095 avox 1522
                                                                        if ((current.yPos > maxDY) && (current.yPos - asce > maxDY))
5362 avox 1523
                                                                        {
1524
                                                                                AbsHasDrop = false;
8095 avox 1525
                                                                                current.xPos = current.colLeft;
5362 avox 1526
                                                                        }
1527
                                                                        else
8095 avox 1528
                                                                                current.xPos = maxDX;
5362 avox 1529
                                                                }
1530
                                                                else
8095 avox 1531
                                                                        current.xPos = current.colLeft;
7887 avox 1532
                                                                if (isBreak(hl->ch[0]))
5362 avox 1533
                                                                {
1534
                                                                        if (hl->ch == SpecialChars::PARSEP)
8095 avox 1535
                                                                                current.yPos += style.gapAfter();
1536
                                                                        current.hyphenCount = 0;
5362 avox 1537
                                                                }
1538
                                                                break;
3614 cbradney 1539
                                                        }
8095 avox 1540
                                                        pt1 = QPoint(qRound(current.xPos+extra.Right), static_cast<int>(current.yPos+BotOffset));
1541
                                                        pt2 = QPoint(qRound(current.xPos+extra.Right), static_cast<int>(ceil(current.yPos-asce)));
1542
                                                        if (cl.contains(pf2.xForm(pt1)) && cl.contains(pf2.xForm(pt2)))
5362 avox 1543
                                                                break;
8095 avox 1544
//                                                      else
1545
//                                                              qDebug(QString("looking for start of line at %1,%2").arg(current.xPos).arg(current.yPos));
5362 avox 1546
                                                }
1547
                                                if (fromOut)
1548
                                                {
8095 avox 1549
                                                        if (current.isEndOfCol(desc) && (current.column+1 == Cols))
3614 cbradney 1550
                                                        {
5362 avox 1551
                                                                goNoRoom = true;
6375 avox 1552
//                                                              qDebug(QString("go no room 2: %1").arg(a));
5362 avox 1553
                                                                break;
3614 cbradney 1554
                                                        }
8095 avox 1555
                                                        current.xPos--;
1556
                                                        current.xPos = QMAX(current.xPos, current.colLeft);
3614 cbradney 1557
                                                }
1558
                                        }
1559
                                        else
1560
                                        {
5362 avox 1561
                                                if (( hl->ch == SpecialChars::PARSEP || hl->ch == SpecialChars::LINEBREAK )
1562
                                                        && AbsHasDrop)
1563
                                                {
1564
                                                        AbsHasDrop = false;
8095 avox 1565
                                                        if (current.yPos < maxDY)
1566
                                                                current.yPos = maxDY;
5362 avox 1567
                                                }
8062 avox 1568
//                                              qDebug(QString("layout: next lower3 grid=%1 x %2").arg(style.lineSpacingMode() == ParagraphStyle::BaselineGridLineSpacing).arg(m_Doc->typographicSettings.valueBaseGrid));
1569
 
1570
                                                if (style.lineSpacingMode() == ParagraphStyle::BaselineGridLineSpacing)
8095 avox 1571
                                                        current.yPos += m_Doc->typographicSettings.valueBaseGrid;
3614 cbradney 1572
                                                else
1573
                                                {
5721 avox 1574
                                                        if (a < lastInFrame())
8095 avox 1575
                                                                current.yPos += itemText.paragraphStyle(a+1).lineSpacing();
3614 cbradney 1576
                                                        else
8095 avox 1577
                                                                current.yPos += style.lineSpacing();
3614 cbradney 1578
                                                }
5362 avox 1579
                                                if (AbsHasDrop)
1580
                                                {
8095 avox 1581
                                                        if ((current.yPos > maxDY) && (current.yPos - asce > maxDY))
5362 avox 1582
                                                        {
1583
                                                                AbsHasDrop = false;
8095 avox 1584
                                                                current.xPos = current.colLeft;
5362 avox 1585
                                                        }
1586
                                                        else
8095 avox 1587
                                                                current.xPos = maxDX;
5362 avox 1588
                                                }
3614 cbradney 1589
                                                else
8095 avox 1590
                                                        current.xPos = current.colLeft;
7887 avox 1591
                                                if ( isBreak(hl->ch[0]) )
5362 avox 1592
                                                {
5721 avox 1593
                                                        if (hl->ch == SpecialChars::PARSEP)
8095 avox 1594
                                                                current.yPos += style.gapAfter();
1595
                                                        current.hyphenCount = 0;
5362 avox 1596
                                                }
3614 cbradney 1597
                                        }
5362 avox 1598
                                }
1599
 
1600
 
6354 avox 1601
                                // calc. needed vertical space
8095 avox 1602
                                if (current.itemsInLine != 0)
5362 avox 1603
                                {
8095 avox 1604
                                        if ((!AbsHasDrop) && (current.startOfCol) && (style.lineSpacingMode() != ParagraphStyle::BaselineGridLineSpacing))
3614 cbradney 1605
                                        {
8095 avox 1606
                                                double firstasce = itemText.charStyle(current.line.firstItem).font().ascent(itemText.charStyle(current.line.firstItem).fontSize() / 10.0);
6370 avox 1607
                                                double currasce = 0;
8095 avox 1608
                                                if ((itemText.text(current.line.firstItem) == SpecialChars::PARSEP) || (itemText.text(current.line.firstItem) == SpecialChars::LINEBREAK))
1609
                                                        currasce = itemText.charStyle(current.line.firstItem).font().ascent(itemText.charStyle(current.line.firstItem).fontSize() / 10.0);
1610
                                                else if (itemText.object(current.line.firstItem) != 0)
1611
                                                        currasce = QMAX(currasce, (itemText.object(current.line.firstItem)->gHeight + itemText.object(current.line.firstItem)->lineWidth()) * (itemText.charStyle(current.line.firstItem).scaleV() / 1000.0));
1612
                                                else //if (itemText.charStyle(current.line.firstItem).effects() & ScStyle_DropCap == 0)
1613
                                                        currasce = itemText.charStyle(current.line.firstItem).font().realCharAscent(itemText.text(current.line.firstItem), itemText.charStyle(current.line.firstItem).fontSize() / 10.0);
1614
                                                for (int zc = 0; zc < current.itemsInLine; ++zc)
3614 cbradney 1615
                                                {
8095 avox 1616
                                                        QChar ch = itemText.text(current.line.firstItem + zc);
1617
                                                        const CharStyle& cStyle(itemText.charStyle(current.line.firstItem + zc));
5980 avox 1618
                                                        if ((ch == SpecialChars::TAB) || (ch == QChar(10))
1619
                                                                || (ch == SpecialChars::PARSEP) || (ch == SpecialChars::NBHYPHEN)
1620
                                                                || (ch == SpecialChars::COLBREAK) || (ch == SpecialChars::LINEBREAK)
1621
                                                                || (ch == SpecialChars::FRAMEBREAK) || (ch == SpecialChars::NBSPACE))
5362 avox 1622
                                                                continue;
8095 avox 1623
                                                        if (itemText.object(current.line.firstItem + zc) != 0)
1624
                                                                currasce = QMAX(currasce, (itemText.object(current.line.firstItem + zc)->gHeight + itemText.object(current.line.firstItem + zc)->lineWidth()) * (cStyle.scaleV() / 1000.0));
1625
                                                        else //if (itemText.charStyle(current.line.firstItem + zc).effects() & ScStyle_DropCap == 0)
5980 avox 1626
                                                                currasce = QMAX(currasce, cStyle.font().realCharAscent(ch, cStyle.fontSize() / 10.0));
3614 cbradney 1627
                                                }
5362 avox 1628
                                                double adj = firstasce - currasce;
8095 avox 1629
                                                current.line.ascent = currasce;
1630
                                                current.line.y -= adj;
1631
                                                current.yPos -= adj;
5362 avox 1632
                                        }
8095 avox 1633
                                        else if ((!current.startOfCol) && (style.lineSpacingMode() != ParagraphStyle::BaselineGridLineSpacing) && (style.lineSpacingMode() == ParagraphStyle::AutomaticLineSpacing))
5362 avox 1634
                                        {
8095 avox 1635
                                                QChar ch = itemText.text(current.line.firstItem);
6805 avox 1636
                                                double firstasce = style.lineSpacing();
5362 avox 1637
                                                double currasce = 0;
8095 avox 1638
                                                if (itemText.object(current.line.firstItem) != 0)
1639
                                                        currasce = QMAX(currasce, (itemText.object(current.line.firstItem)->gHeight + itemText.object(current.line.firstItem)->lineWidth()) * (itemText.charStyle(current.line.firstItem).scaleV() / 1000.0));
1640
                                                else //if (itemText.charStyle(current.line.firstItem).effects() & ScStyle_DropCap == 0)
1641
                                                        currasce = itemText.charStyle(current.line.firstItem).font().height(itemText.charStyle(current.line.firstItem).fontSize() / 10.0);
1642
                                                for (int zc = 0; zc < current.itemsInLine; ++zc)
3614 cbradney 1643
                                                {
8095 avox 1644
                                                        QChar ch = itemText.text(current.line.firstItem + zc);
5980 avox 1645
                                                        if ((ch == SpecialChars::TAB) || (ch == QChar(10))
7905 avox 1646
                                                                || (ch == SpecialChars::PARSEP) || (ch == SpecialChars::NBHYPHEN)
1647
                                                                || (ch == SpecialChars::COLBREAK) || (ch == SpecialChars::FRAMEBREAK)
1648
                                                                || (ch == SpecialChars::LINEBREAK) || (ch == SpecialChars::NBSPACE))
5362 avox 1649
                                                                continue;
8095 avox 1650
                                                        if (itemText.object(current.line.firstItem + zc) != 0)
1651
                                                                currasce = QMAX(currasce, (itemText.object(current.line.firstItem + zc)->gHeight + itemText.object(current.line.firstItem + zc)->lineWidth()) * (itemText.charStyle(current.line.firstItem + zc).scaleV() / 1000.0));
1652
                                                        else //if (itemText.charStyle(current.line.firstItem + zc).effects() & ScStyle_DropCap == 0)
1653
                                                                currasce = QMAX(currasce, itemText.charStyle(current.line.firstItem + zc).font().height(itemText.charStyle(current.line.firstItem + zc).fontSize() / 10.0));
3614 cbradney 1654
                                                }
6370 avox 1655
 
5362 avox 1656
                                                double adj = firstasce - currasce;
8095 avox 1657
                                                current.line.ascent = currasce;
1658
                                                current.line.y -= adj;
1659
                                                current.yPos -= adj;
3614 cbradney 1660
                                        }
8095 avox 1661
                                        if ( itemText.charStyle(current.line.firstItem).effects() & ScStyle_DropCap)
6370 avox 1662
                                        {
1663
                                                // put line back to top
8095 avox 1664
                                                current.line.y -= DropCapDrop;
1665
                                                itemText.item(current.line.firstItem)->glyph.yoffset += DropCapDrop;
6370 avox 1666
                                        }
5362 avox 1667
                                }
6144 avox 1668
 
8095 avox 1669
                                fillInTabLeaders(itemText, current.line);
7905 avox 1670
 
8095 avox 1671
                                current.startOfCol = false;
6144 avox 1672
/* has no effect except setting wide, asce and desc
1673
                                uint loopC = BuPos3;
5362 avox 1674
                                if (m_Doc->guidesSettings.showControls)
1675
                                        loopC++;  // ??? AV
5980 avox 1676
                                for (int zc = 0; zc < loopC; ++zc)
5362 avox 1677
                                {
8095 avox 1678
                                        if ( zc >= current.itemsInLine) {
1679
                                                qDebug("layout: zc too large %d / %d", zc, current.itemsInLine);
5751 avox 1680
                                                continue;
1681
                                        }
5980 avox 1682
                                        if ( startLin + zc >= itemText.length()) {
5751 avox 1683
                                                qDebug("layout: startLin+zc too large %d+%d / %d", startLin, zc, itemText.length());
1684
                                                continue;
1685
                                        }
1686
//                                      else
1687
//                                              qDebug("layout: startLin, zc ok. %d, %d, %d", startLin, zc, LiList.count());
5362 avox 1688
                                        double wide2 = 0;
8095 avox 1689
                                        double xcoZli = itemText.item(current.line.firstItem + zc)->glyph.xoffset;
5980 avox 1690
//                                      itemText.item(startLin+zc)->glyph.xoffset = Zli2->xco;
1691
///                                     itemText.item(startLin+zc)->glyph.yoffset = Zli2->yco;
5721 avox 1692
                                        tTabValues = itemText.paragraphStyle(startLin+zc).tabValues();
5980 avox 1693
                                        desc = - itemText.charStyle(startLin+zc).font().descent(itemText.charStyle(startLin+zc).fontSize() / 10.0);
1694
                                        asce = itemText.charStyle(startLin+zc).font().ascent(itemText.charStyle(startLin+zc).fontSize() / 10.0);
1695
                                        bool Sele = itemText.selected(startLin+zc);
1696
                                        if (((Sele && (Select)) || (((NextBox != 0) || (BackBox != 0)) && Sele)) && (m_Doc->appMode == modeEdit))
3614 cbradney 1697
                                        {
5980 avox 1698
                                                wide = itemText.item(startLin+zc)->glyph.xadvance;
1699
                                                if ((zc > 0) && (itemText.text(startLin+zc) == SpecialChars::TAB))
3614 cbradney 1700
                                                {
5980 avox 1701
                                                        wide2 = itemText.item(startLin+zc-1)->glyph.xadvance;
1702
                                                        xcoZli = itemText.item(startLin+zc-1)->glyph.xoffset + wide2;
1703
                                                        wide = itemText.item(startLin+zc)->glyph.xoffset - xcoZli + itemText.item(startLin+zc)->glyph.xadvance;
3614 cbradney 1704
                                                }
5362 avox 1705
                                        }
1706
                                }
6144 avox 1707
                                */
8095 avox 1708
//                              qDebug(QString("layout: line %1 - %2 @ (%3,%4) wd %5/%6").arg(current.line.firstItem).arg(current.line.lastItem)
1709
//                                         .arg(current.line.x).arg(current.line.y).arg(current.line.naturalWidth).arg(current.line.width));
1710
                                if (current.line.firstItem > current.line.lastItem)
1711
                                        qDebug(QString("layout: empty line %1 - %2").arg(current.line.firstItem).arg(current.line.lastItem));
1712
                                else if (current.itemsInLine > 0)
1713
                                        itemText.appendLine(current.line);
1714
                                current.startLine(a+1);
5362 avox 1715
                                outs = false;
1716
                                if (goNoRoom)
1717
                                {
1718
                                        goNoRoom = false;
8095 avox 1719
                                        MaxChars = a+1;
6375 avox 1720
//                                      qDebug(QString("no room C: %1").arg(a+1));
5362 avox 1721
                                        goto NoRoom;
1722
                                }
1723
                                if (goNextColumn)
1724
                                {
1725
                                        goNextColumn = false;
8095 avox 1726
                                        current.column++;
1727
                                        if (current.column < Cols)
5362 avox 1728
                                        {
8095 avox 1729
                                                current.nextColumn(asce);
5362 avox 1730
                                        }
1731
                                        else
1732
                                        {
8095 avox 1733
                                                MaxChars = a;
6375 avox 1734
//                                              qDebug(QString("no room D: %1").arg(a));
5362 avox 1735
                                                goto NoRoom;
1736
                                        }
1737
                                }
1738
                        }
1739
                }
5980 avox 1740
// end of itemText
8060 avox 1741
                int a = itemText.length()-1;
7969 avox 1742
                hl = a >=0 ? itemText.item(a) : NULL;
8095 avox 1743
                current.breakLine(itemText, a);
1744
                EndX = current.endOfLine(cl, pf2, asce, desc, style.rightMargin());
1745
                current.finishLine(EndX);
1746
 
6805 avox 1747
                if (style.alignment() != 0)
5362 avox 1748
                {
8095 avox 1749
                        if (opticalMargins & ParagraphStyle::OM_RightHangingPunct)
1750
                        {
1751
                                current.line.width += opticalRightMargin(itemText, current.line);
5414 avox 1752
                        }
8095 avox 1753
 
1754
                        OFs = 0;
6805 avox 1755
                        if (style.alignment() == 2)
8095 avox 1756
                                OFs = current.line.width - current.line.naturalWidth;
6805 avox 1757
                        if (style.alignment() == 1)
8095 avox 1758
                                OFs = (current.line.width - current.line.naturalWidth) / 2;
6805 avox 1759
                        if (style.alignment() == 3)
5362 avox 1760
                                OFs = 0;
7037 avox 1761
                        if (style.alignment() == 4
1762
                                || (style.alignment() == 3
7287 avox 1763
                                        &&  (hl->ch == SpecialChars::LINEBREAK ||
1764
                                                 hl->ch == SpecialChars::FRAMEBREAK ||
1765
                                                 hl->ch == SpecialChars::COLBREAK)
8095 avox 1766
                                        &&  !itemText.text(current.line.firstItem + current.itemsInLine-1).isSpace()))
5362 avox 1767
                        {
8095 avox 1768
                                justifyLine(itemText, current.line);
5362 avox 1769
                        }
1770
                        else
1771
                        {
8095 avox 1772
                                indentLine(current.line, OFs);
5362 avox 1773
                        }
1774
                }
8095 avox 1775
 
1776
                if (current.itemsInLine != 0)