LDEBUG << " do layout";
QTextOption option = docPrivate->defaultTextOption;
option.setTextDirection(dir);
- option.setTabs( blockFormat.tabPositions() );
Qt::Alignment align = docPrivate->defaultTextOption.alignment();
if (blockFormat.hasProperty(QTextFormat::BlockAlignment))
dpiScale = QFixed::fromReal(fnt.d->dpi / qreal(QX11Info::appDpiY()));
}
- QList<QTextOption::Tab> tabArray = option.tabs();
- if (!tabArray.isEmpty()) {
- for (int i = 0; i < tabArray.size(); ++i) {
- QFixed tab = QFixed::fromReal(tabArray[i].position) * dpiScale;
- if (tab > x) { // this is the tab we need.
- QTextOption::Tab tabSpec = tabArray[i];
- int tabSectionEnd = layoutData->string.count();
- if (tabSpec.type == QTextOption::RightTab || tabSpec.type == QTextOption::CenterTab) {
- // find next tab to calculate the width required.
- tab = QFixed::fromReal(tabSpec.position);
- for (int i=item + 1; i < layoutData->items.count(); i++) {
- const QScriptItem &item = layoutData->items[i];
- if (item.analysis.flags == QScriptAnalysis::TabOrObject) { // found it.
- tabSectionEnd = item.position;
- break;
- }
- }
- }
- else if (tabSpec.type == QTextOption::DelimiterTab)
- // find delimitor character to calculate the width required
- tabSectionEnd = qMax(si.position, layoutData->string.indexOf(tabSpec.delimiter, si.position) + 1);
-
- if (tabSectionEnd > si.position) {
- QFixed length;
- // Calculate the length of text between this tab and the tabSectionEnd
- for (int i=item; i < layoutData->items.count(); i++) {
- QScriptItem &item = layoutData->items[i];
- if (item.position > tabSectionEnd || item.position <= si.position)
- continue;
- shape(i); // first, lets make sure relevant text is already shaped
- QGlyphLayout glyphs = this->shapedGlyphs(&item);
- const int end = qMin(item.position + item.num_glyphs, tabSectionEnd) - item.position;
- for (int i=0; i < end; i++)
- length += glyphs.advances_x[i] * !glyphs.attributes[i].dontPrint;
- if (end + item.position == tabSectionEnd && tabSpec.type == QTextOption::DelimiterTab) // remove half of matching char
- length -= glyphs.advances_x[end] / 2 * !glyphs.attributes[end].dontPrint;
- }
-
- switch (tabSpec.type) {
- case QTextOption::CenterTab:
- length /= 2;
- // fall through
- case QTextOption::DelimiterTab:
- // fall through
- case QTextOption::RightTab:
- tab = QFixed::fromReal(tabSpec.position) * dpiScale - length;
- if (tab < 0) // default to tab taking no space
- return QFixed();
- break;
- case QTextOption::LeftTab:
- break;
- }
- }
- return tab - x;
- }
- }
- }
QFixed tab = QFixed::fromReal(option.tabStop());
if (tab <= 0)
tab = 80; // default
\value BlockLeftMargin
\value BlockRightMargin
\value TextIndent
- \value TabPositions Specifies the tab positions. The tab positions are structs of QTextOption::Tab which are stored in
- a QList (internally, in a QList<QVariant>).
\value BlockIndent
\value LineHeight
\value LineHeightType
}
/*!
- \since 4.4
- Sets the tab positions for the text block to those specified by
- \a tabs.
-
- \sa tabPositions()
-*/
-void QTextBlockFormat::setTabPositions(const QList<QTextOption::Tab> &tabs)
-{
- QList<QVariant> list;
- QList<QTextOption::Tab>::ConstIterator iter = tabs.constBegin();
- while (iter != tabs.constEnd()) {
- QVariant v;
- v.setValue<QTextOption::Tab>(*iter);
- list.append(v);
- ++iter;
- }
- setProperty(TabPositions, list);
-}
-
-/*!
- \since 4.4
- Returns a list of tab positions defined for the text block.
-
- \sa setTabPositions()
-*/
-QList<QTextOption::Tab> QTextBlockFormat::tabPositions() const
-{
- QVariant variant = property(TabPositions);
- if(variant.isNull())
- return QList<QTextOption::Tab>();
- QList<QTextOption::Tab> answer;
- QList<QVariant> variantsList = qvariant_cast<QList<QVariant> >(variant);
- QList<QVariant>::Iterator iter = variantsList.begin();
- while(iter != variantsList.end()) {
- answer.append( qvariant_cast<QTextOption::Tab>(*iter));
- ++iter;
- }
- return answer;
-}
-
-/*!
\fn QTextBlockFormat::isValid() const
Returns true if this block format is valid; otherwise returns
BlockLeftMargin = 0x1032,
BlockRightMargin = 0x1033,
TextIndent = 0x1034,
- TabPositions = 0x1035,
BlockIndent = 0x1040,
LineHeight = 0x1048,
LineHeightType = 0x1049,
inline PageBreakFlags pageBreakPolicy() const
{ return PageBreakFlags(intProperty(PageBreakPolicy)); }
- void setTabPositions(const QList<QTextOption::Tab> &tabs);
- QList<QTextOption::Tab> tabPositions() const;
-
protected:
explicit QTextBlockFormat(const QTextFormat &fmt);
friend class QTextFormat;
QT_BEGIN_NAMESPACE
-struct QTextOptionPrivate
-{
- QList<QTextOption::Tab> tabStops;
-};
-
/*!
Constructs a text option with default properties for text.
The text alignment property is set to Qt::AlignLeft. The
align(Qt::AlignLeft),
direction(Qt::LayoutDirectionAuto),
design(false),
- tab(-1),
- d(0)
+ tab(-1)
{
}
align(alignment),
direction(QApplication::layoutDirection()),
design(false),
- tab(-1),
- d(0)
+ tab(-1)
{
}
*/
QTextOption::~QTextOption()
{
- delete d;
}
/*!
align(o.align),
direction(o.direction),
design(o.design),
- tab(o.tab),
- d(0)
+ tab(o.tab)
{
- if (o.d)
- d = new QTextOptionPrivate(*o.d);
}
/*!
if (this == &o)
return *this;
- QTextOptionPrivate* dNew = 0;
- if (o.d)
- dNew = new QTextOptionPrivate(*o.d);
- delete d;
- d = dNew;
-
wordwrap = o.wordwrap;
fflags = o.fflags;
align = o.align;
}
/*!
- Sets the tab positions for the text layout to those specified by
- \a tabStops.
-
- \sa tabArray(), setTabStop(), setTabs()
-*/
-void QTextOption::setTabArray(const QList<qreal> &tabStops)
-{
- if (!d)
- d = new QTextOptionPrivate;
- QList<QTextOption::Tab> tabs;
- QTextOption::Tab tab;
- foreach (qreal pos, tabStops) {
- tab.position = pos;
- tabs.append(tab);
- }
- d->tabStops = tabs;
-}
-
-/*!
- \since 4.4
- Sets the tab positions for the text layout to those specified by
- \a tabStops.
-
- \sa tabStops()
-*/
-void QTextOption::setTabs(const QList<QTextOption::Tab> &tabStops)
-{
- if (!d)
- d = new QTextOptionPrivate;
- d->tabStops = tabStops;
-}
-
-/*!
- Returns a list of tab positions defined for the text layout.
-
- \sa setTabArray(), tabStop()
-*/
-QList<qreal> QTextOption::tabArray() const
-{
- if (!d)
- return QList<qreal>();
-
- QList<qreal> answer;
- foreach(const QTextOption::Tab tab, d->tabStops) {
- answer.append(tab.position);
- }
- return answer;
-}
-
-
-QList<QTextOption::Tab> QTextOption::tabs() const
-{
- if (!d)
- return QList<QTextOption::Tab>();
- return d->tabStops;
-}
-
-/*!
\class QTextOption
\reentrant
Returns the distance in device units between tab stops.
Convenient function for the above method
- \sa setTabStop(), tabArray(), setTabs(), tabs()
+ \sa setTabStop()
*/
/*!
Sets the default distance in device units between tab stops to the value specified
by \a tabStop.
- \sa tabStop(), setTabArray(), setTabs(), tabs()
+ \sa tabStop()
*/
-/*!
- \enum QTextOption::TabType
- \since 4.4
-
- This enum holds the different types of tabulator
-
- \value LeftTab A left-tab
- \value RightTab A right-tab
- \value CenterTab A centered-tab
- \value DelimiterTab A tab stopping at a certain delimiter-character
-*/
-
-/*!
- \class QTextOption::Tab
- \since 4.4
- Each tab definition is represented by this struct.
-*/
-
-/*!
- \variable Tab::position
- Distance from the start of the paragraph.
- The position of a tab is from the start of the paragraph which implies that when
- the alignment of the paragraph is set to centered, the tab is interpreted to be
- moved the same distance as the left ege of the paragraph does.
- In case the paragraph is set to have a layoutDirection() RightToLeft the position
- is interpreted to be from the right side of the paragraph with higher numbers moving
- the tab to the left.
-*/
-
-/*!
- \variable Tab::type
- Determine which type is used.
- In a paragraph that has layoutDirection() RightToLeft the type LeftTab will
- be interpreted to be a RightTab and vice versa.
-*/
-
-/*!
- \variable Tab::delimiter
- If type is DelimitorTab; tab until this char is found in the text.
-*/
-
-/*!
- \fn Tab::Tab()
- Creates a default left tab with position 80.
-*/
-
-/*!
- \fn Tab::Tab(qreal pos, TabType tabType, QChar delim = QChar())
-
- Creates a tab with the given position, tab type, and delimiter
- (\a pos, \a tabType, \a delim).
-
- \note \a delim is only used when \a tabType is DelimiterTab.
-
- \since 4.7
-*/
-
-/*!
- \fn bool Tab::operator==(const Tab &other) const
-
- Returns true if tab \a other is equal to this tab;
- otherwise returns false.
-*/
-
-/*!
- \fn bool Tab::operator!=(const Tab &other) const
-
- Returns true if tab \a other is not equal to this tab;
- otherwise returns false.
-*/
-
-/*!
- \fn void setTabs(QList<Tab> tabStops)
- Set the Tab properties to \a tabStops.
-
- \sa tabStop(), tabs()
-*/
-
-/*!
- \since 4.4
- \fn QList<QTextOption::Tab> QTextOption::tabs() const
- Returns a list of tab positions defined for the text layout.
-
- \sa tabStop(), setTabs(), setTabStop()
-*/
-
-
QT_END_NAMESPACE
#include "moc_qtextoption.h"
{
Q_GADGET
public:
- enum TabType {
- LeftTab,
- RightTab,
- CenterTab,
- DelimiterTab
- };
-
- struct Q_GUI_EXPORT Tab {
- inline Tab() : position(80), type(QTextOption::LeftTab) { }
- inline Tab(qreal pos, TabType tabType, QChar delim = QChar())
- : position(pos), type(tabType), delimiter(delim) {}
-
- inline bool operator==(const Tab &other) const {
- return type == other.type
- && qFuzzyCompare(position, other.position)
- && delimiter == other.delimiter;
- }
-
- inline bool operator!=(const Tab &other) const {
- return !operator==(other);
- }
-
- qreal position;
- TabType type;
- QChar delimiter;
- };
-
QTextOption();
QTextOption(Qt::Alignment alignment);
~QTextOption();
inline void setTabStop(qreal tabStop);
inline qreal tabStop() const { return tab; }
- void setTabArray(const QList<qreal> &tabStops);
- QList<qreal> tabArray() const;
-
- void setTabs(const QList<Tab> &tabStops);
- QList<Tab> tabs() const;
-
void setUseDesignMetrics(bool b) { design = b; }
bool useDesignMetrics() const { return design; }
Qt::LayoutDirection direction;
bool design;
qreal tab;
- QTextOptionPrivate *d;
};
Q_DECLARE_OPERATORS_FOR_FLAGS(QTextOption::Flags)
QT_END_NAMESPACE
-Q_DECLARE_METATYPE( QTextOption::Tab )
-
-
#endif // QTEXTOPTION_H
void testUnderlinePropertyPrecedence();
void toFormat();
void resolveFont();
- void getSetTabs();
- void testTabsUsed();
void testFontStyleSetters();
};
QVERIFY(fmt.font().strikeOut());
}
-void tst_QTextFormat::getSetTabs()
-{
- class Comparator {
- public:
- Comparator(const QList<QTextOption::Tab> &tabs, const QList<QTextOption::Tab> &tabs2)
- {
- QCOMPARE(tabs.count(), tabs2.count());
- for(int i=0; i < tabs.count(); i++) {
- QTextOption::Tab t1 = tabs[i];
- QTextOption::Tab t2 = tabs2[i];
- QCOMPARE(t1.position, t2.position);
- QCOMPARE(t1.type, t2.type);
- QCOMPARE(t1.delimiter, t2.delimiter);
- }
- }
- };
-
- QList<QTextOption::Tab> tabs;
- QTextBlockFormat format;
- format.setTabPositions(tabs);
- Comparator c1(tabs, format.tabPositions());
-
- QTextOption::Tab tab1;
- tab1.position = 1234;
- tabs.append(tab1);
- format.setTabPositions(tabs);
- Comparator c2(tabs, format.tabPositions());
-
- QTextOption::Tab tab2(3456, QTextOption::RightTab, QChar('x'));
- tabs.append(tab2);
- format.setTabPositions(tabs);
- Comparator c3(tabs, format.tabPositions());
-}
-
-void tst_QTextFormat::testTabsUsed()
-{
- QTextDocument doc;
- QTextCursor cursor(&doc);
-
- QList<QTextOption::Tab> tabs;
- QTextBlockFormat format;
- QTextOption::Tab tab;
- tab.position = 100;
- tabs.append(tab);
- format.setTabPositions(tabs);
- cursor.mergeBlockFormat(format);
- cursor.insertText("foo\tbar");
- //doc.setPageSize(QSizeF(200, 200));
- doc.documentLayout()->pageCount(); // force layout;
-
- QTextBlock block = doc.begin();
- QTextLayout *layout = block.layout();
- QVERIFY(layout);
- QCOMPARE(layout->lineCount(), 1);
- QTextLine line = layout->lineAt(0);
- QCOMPARE(line.cursorToX(4), 100.);
-
- QTextOption option = layout->textOption();
- QCOMPARE(option.tabs().count(), tabs.count());
-
-}
-
void tst_QTextFormat::testFontStyleSetters()
{
QTextCharFormat format;