Subversion Repositories Scribus

Rev

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