Back to index

scribus-ng  1.3.4.dfsg+svn20071115
Classes | Enumerations | Functions | Variables
pageitem_textframe.cpp File Reference
#include "pageitem_textframe.h"
#include "pageitem_textframe.moc"
#include <qpainter.h>
#include <qpen.h>
#include <qfont.h>
#include <qregion.h>
#include <qpoint.h>
#include <qfileinfo.h>
#include <qdrawutil.h>
#include <qbitmap.h>
#include <qregexp.h>
#include <qmessagebox.h>
#include <cmath>
#include <cassert>
#include "hyphenator.h"
#include "mpalette.h"
#include "page.h"
#include "pageitem.h"
#include "prefsmanager.h"
#include "scpaths.h"
#include "scribus.h"
#include "scribusstructs.h"
#include "scribusdoc.h"
#include "selection.h"
#include "undomanager.h"
#include "undostate.h"
#include "scconfig.h"
#include "commonstrings.h"
#include "guidemanager.h"
#include "util.h"
#include "text/nlsconfig.h"

Go to the source code of this file.

Classes

struct  TabControl
 fields which describe what type of tab is currently active More...
struct  LineControl
 fields which describe how the current line is placed into the frame More...

Enumerations

enum  TabStatus {
  TabNONE = 0, TabLEFT = TabNONE, TabRIGHT = 1, TabPOINT = 2,
  TabCOMMA = 3, TabCENTER = 4
}

Functions

static QRegion itemShape (PageItem *docItem, ScribusView *view, double xOffset, double yOffset)
static void dumpIt (const ParagraphStyle &pstyle, QString indent=QString("->"))
static void fillInTabLeaders (StoryText &itemText, LineSpec &curLine)
 Clones the tab fill char as often as necssary after all distances are known.
static void justifyLine (StoryText &itemText, LineSpec &line)
 called when line length is known and line is to be justified
static void indentLine (StoryText &itemText, LineSpec &line, double leftIndent)
 called when linelength is known and line is not justified
static double opticalLeftMargin (const StoryText &itemText, const LineSpec &line)
 calculate how much the first char should stick out to the left
static double opticalRightMargin (const StoryText &itemText, const LineSpec &line)
 calculate how much the last char should stick out to the right

Variables

static const bool legacy = true

Class Documentation

struct TabControl

fields which describe what type of tab is currently active

Definition at line 284 of file pageitem_textframe.cpp.

Class Members
bool active
int charIndex
QChar fillChar
int status
double xPos

Enumeration Type Documentation

enum TabStatus
Enumerator:
TabNONE 
TabLEFT 
TabRIGHT 
TabPOINT 
TabCOMMA 
TabCENTER 

Definition at line 271 of file pageitem_textframe.cpp.

               {
       TabNONE    = 0,
       TabLEFT    = TabNONE,
       TabRIGHT   = 1,
       TabPOINT   = 2,
       TabCOMMA   = 3,
       TabCENTER  = 4
};

Function Documentation

static void dumpIt ( const ParagraphStyle &  pstyle,
QString  indent = QString("->") 
) [static]

Definition at line 205 of file pageitem_textframe.cpp.

{
       qDebug(QString("%6%1/%2 @ %3: %4--%5 linespa%6: %7 align%8")
                 .arg(pstyle.name())
                 .arg(pstyle.parent())
                 .arg( (unsigned long int) &pstyle)
                 .arg(pstyle.leftMargin())
                 .arg(pstyle.rightMargin())
                 .arg(indent)
                 .arg(pstyle.lineSpacingMode())
                 .arg(pstyle.lineSpacing())
                 .arg(pstyle.alignment()));
       static QString more("  ");
       if (pstyle.hasParent())
              dumpIt(*dynamic_cast<const ParagraphStyle*>(pstyle.parentStyle()), more + indent);
}
static void fillInTabLeaders ( StoryText &  itemText,
LineSpec curLine 
) [static]

Clones the tab fill char as often as necssary after all distances are known.

Definition at line 234 of file pageitem_textframe.cpp.

{
       // fill in tab leaders
       double xPos = curLine.x;
       for (int ti= curLine.firstItem; ti < curLine.lastItem; ++ti)
       {
              ScText * hl = itemText.item(ti);
              if (hl->ch[0] == SpecialChars::TAB) 
              {
                     GlyphLayout * tglyph = hl->glyph.more;
                     
                     if (!tglyph)
                            continue;
                     
                     const CharStyle & charStyle(itemText.charStyle(ti));
                     double wt   = charStyle.font().glyphWidth(tglyph->glyph, charStyle.fontSize() * tglyph->scaleV / 10.0);
                     double len  = hl->glyph.xadvance;
                     int count   = static_cast<int>(len / wt);
                     double sPos = -len;
                     tglyph->xoffset = sPos;
//                   qDebug(QString("tab leaders: %1 %2 width=%3 count=%4").arg(sPos).arg(curLine.y).arg(wt).arg(count));
                     for (int cx = 1; cx < count; ++cx)
                     {
                            // clone fillchar
                            tglyph->grow();
                            *(tglyph->more) = *tglyph;
                            tglyph->more->more = NULL;
                            tglyph = tglyph->more;
                            tglyph->xoffset =  sPos + wt * cx;
                     }
              }
              xPos += hl->glyph.wide();
       }
}
static void indentLine ( StoryText &  itemText,
LineSpec line,
double  leftIndent 
) [static]

called when linelength is known and line is not justified

Definition at line 621 of file pageitem_textframe.cpp.

{
       if (line.naturalWidth > line.width)
       {
              justifyLine(itemText, line);
       }
       if (leftIndent > 0)
       {
              line.x += leftIndent;
              line.width -= leftIndent;
       }
}

Here is the call graph for this function:

static QRegion itemShape ( PageItem *  docItem,
ScribusView *  view,
double  xOffset,
double  yOffset 
) [static]

Definition at line 73 of file pageitem_textframe.cpp.

{
       QRegion res;
       QPainter pp;
       pp.begin(view->viewport());
       pp.translate(docItem->xPos() - xOffset, docItem->yPos() - yOffset);
       pp.rotate(docItem->rotation());
       if (docItem->textFlowUsesBoundingBox())
       {
              QPointArray tcli(4);
              tcli.setPoint(0, QPoint(0,0));
              tcli.setPoint(1, QPoint(qRound(docItem->width()), 0));
              tcli.setPoint(2, QPoint(qRound(docItem->width()), qRound(docItem->height())));
              tcli.setPoint(3, QPoint(0, qRound(docItem->height())));
              res = QRegion(pp.xForm(tcli));
       }
       else if ((docItem->textFlowUsesImageClipping()) && (docItem->imageClip.size() != 0))
       {
              QValueList<uint> Segs;
              QPointArray Clip2 = FlattenPath(docItem->imageClip, Segs);
              res = QRegion(pp.xForm(Clip2)).intersect(QRegion(pp.xForm(docItem->Clip)));
       }
       else if ((docItem->textFlowUsesContourLine()) && (docItem->ContourLine.size() != 0))
       {
              QValueList<uint> Segs;
              QPointArray Clip2 = FlattenPath(docItem->ContourLine, Segs);
              res = QRegion(pp.xForm(Clip2));
       }
       else
              res = QRegion(pp.xForm(docItem->Clip));
       pp.end();
       return  res;
}

Here is the call graph for this function:

static void justifyLine ( StoryText &  itemText,
LineSpec line 
) [static]

called when line length is known and line is to be justified

Definition at line 545 of file pageitem_textframe.cpp.

{
       double glyphNatural = 0;
       double spaceNatural = 0;
       double glyphExtension;
       double spaceExtension;
       
       const ParagraphStyle& style(itemText.paragraphStyle(line.firstItem));
       
       // measure natural widths for glyphs and spaces
       for (int sof = line.firstItem; sof <= line.lastItem; ++sof)
       {
              if (!SpecialChars::isExpandingSpace(itemText.text(sof)))
              {
                     glyphNatural += itemText.item(sof)->glyph.wide();
              }
              else if ((itemText.item(sof)->effects() & ScStyle_SuppressSpace) == 0)
              {
                     spaceNatural += itemText.item(sof)->glyph.wide();
              }
       }
       
       // decision: prio 1: stretch glyph;  prio 2: stretch spaces
       
       if (line.width < spaceNatural + glyphNatural * style.minGlyphExtension() && spaceNatural > 0)
       {
              glyphExtension = style.minGlyphExtension() - 1;
              spaceExtension = (line.width - glyphNatural * (1+glyphExtension) ) / spaceNatural  - 1;
       }
       else if (line.width < spaceNatural + glyphNatural * style.maxGlyphExtension() && glyphNatural > 0)
       {
              spaceExtension = 0;
              glyphExtension = (line.width - spaceNatural) / glyphNatural  - 1;
       }
       else
       {
              glyphExtension = style.maxGlyphExtension() - 1;
              if (spaceNatural > 0)
                     spaceExtension = (line.width - glyphNatural * (1+glyphExtension) ) / spaceNatural  - 1;
              else
                     spaceExtension = 0;
       }
       
       double glyphScale = 1 + glyphExtension;
       
/*
       qDebug(QString("justify: line = %7 natural = %1 + %2 = %3 (%4); spaces + %5%%; min=%8; glyphs + %6%%; min=%9")
                 .arg(spaceNatural).arg(glyphNatural).arg(spaceNatural+glyphNatural).arg(line.naturalWidth)
                 .arg(spaceExtension).arg(glyphExtension).arg(line.width)
                 .arg(style.minWordTracking()).arg(style.minGlyphExtension()));
       */
       
       // distribute whitespace on spaces and glyphs
       for (int yof = line.firstItem; yof <= line.lastItem; ++yof)
       {
              double wide = itemText.item(yof)->glyph.wide();
              if (!SpecialChars::isExpandingSpace(itemText.text(yof)))
              {
                     itemText.item(yof)->glyph.last()->xadvance += wide * glyphExtension;
                     GlyphLayout* glyph = &(itemText.item(yof)->glyph);
                     while (glyph)
                     {
                            glyph->xoffset *= glyphScale;
                            glyph->scaleH *= glyphScale;
                            glyph = glyph->more;
                     }
              }
              else if ((itemText.item(yof)->effects() & ScStyle_SuppressSpace) == 0)
              {
                     itemText.item(yof)->glyph.last()->xadvance += wide * spaceExtension;
              }
       }
}

Here is the caller graph for this function:

static double opticalLeftMargin ( const StoryText &  itemText,
const LineSpec line 
) [static]

calculate how much the first char should stick out to the left

Definition at line 635 of file pageitem_textframe.cpp.

{
       int b = line.firstItem;
       while (b < line.lastItem && (itemText.item(b)->effects() & ScStyle_SuppressSpace))
                 ++b;
       
       double chs = itemText.charStyle(b).fontSize() * (itemText.charStyle(b).scaleH() / 1000.0);
       QChar chr = itemText.text(b);
       double leftCorr = itemText.charStyle(b).font().realCharWidth(chr, chs / 10.0);
       if (QString("'´`").find(chr) >= 0
              || chr == QChar(0x2018) // quote 6
              || chr == QChar(0x2019) // quote 9
              || chr == QChar(0x201a) // lower quote 9
              || chr == QChar(0x201b) // upper reversed 9 6
              || chr == QChar(0x2039) // single guillemet <
              || chr == QChar(0x203a) // single guillemet >
              )
              leftCorr *= -0.7;
       else if (QString("\"").find(chr) >= 0
                      || chr == QChar(0x00ab) // guillemet <<
                      || chr == QChar(0x00bb) // guillemet >>
                      || chr == QChar(0x201c) // quote 66
                      || chr == QChar(0x201d) // quote 99
                      || chr == QChar(0x201e) // lower quote 99
                      || chr == QChar(0x201f) // upper reversed 99
                      ) 
              leftCorr *= -0.5;
       else {
              leftCorr = itemText.charStyle(b).font().charWidth(QChar(' '), chs / 10.0, chr);
              leftCorr -= itemText.charStyle(b).font().charWidth(QChar(' '), chs / 10.0);
//                          double leftCorr2 = itemText.charStyle(a).font().charWidth(QChar('K'), chs / 10.0, chr);
//                          leftCorr2 -= itemText.charStyle(a).font().charWidth(QChar('K'), chs / 10.0);
//                          leftCorr = QMIN(leftCorr, leftCorr2);
       }
       return leftCorr;
}
static double opticalRightMargin ( const StoryText &  itemText,
const LineSpec line 
) [static]

calculate how much the last char should stick out to the right

Definition at line 675 of file pageitem_textframe.cpp.

{
       int b = line.lastItem;
       while (b > line.firstItem && 
                 (SpecialChars::isBreakingSpace(itemText.text(b)) || SpecialChars::isBreak(itemText.text(b)))
                 )
              --b;
       if (b >= line.firstItem) 
       {
              double chs = itemText.charStyle(b).fontSize() * (itemText.charStyle(b).scaleH() / 1000.0);
              QChar chr = (itemText.item(b)->effects() & ScStyle_SmartHyphenVisible) ? 
                     QChar('-') : itemText.text(b);
              double rightCorr = itemText.charStyle(b).font().realCharWidth(chr, chs / 10.0);
              if (QString("-,.`´'~").find(chr) >= 0
                     || chr == QChar(0x2018)
                     || chr == QChar(0x2019)
                     || chr == QChar(0x201a)
                     || chr == QChar(0x201b)
                     || chr == QChar(0x2039)
                     || chr == QChar(0x203a)
                     || chr == QChar(0x2032) // PRIME
                     )
                     rightCorr *= 0.7;
              else if (QString(";:\"").find(chr) >= 0
                             || chr == QChar(0x00ab)
                             || chr == QChar(0x00bb)
                             || chr == QChar(0x201c)
                             || chr == QChar(0x201d)
                             || chr == QChar(0x201e)
                             || chr == QChar(0x201f)
                             || chr == QChar(0x2013) // EN DASH
                             || chr == QChar(0x2033) // double prime
                             )
                     rightCorr *= 0.5;
              else {
                     rightCorr = itemText.charStyle(b).font().charWidth(chr, chs / 10.0);
                     rightCorr -= itemText.charStyle(b).font().charWidth(chr, chs / 10.0, QChar('.'));
              }
              return rightCorr;
       }
       return 0.0;
}

Variable Documentation

const bool legacy = true [static]

Definition at line 223 of file pageitem_textframe.cpp.