summaryrefslogtreecommitdiffstats
path: root/src/gui/text
diff options
context:
space:
mode:
Diffstat (limited to 'src/gui/text')
-rw-r--r--src/gui/text/qabstracttextdocumentlayout.h2
-rw-r--r--src/gui/text/qabstracttextdocumentlayout_p.h6
-rw-r--r--src/gui/text/qcssparser.cpp21
-rw-r--r--src/gui/text/qcssparser_p.h14
-rw-r--r--src/gui/text/qcssscanner.cpp847
-rw-r--r--src/gui/text/qdistancefield.cpp2
-rw-r--r--src/gui/text/qdistancefield_p.h4
-rw-r--r--src/gui/text/qfont.cpp194
-rw-r--r--src/gui/text/qfont.h23
-rw-r--r--src/gui/text/qfont_p.h14
-rw-r--r--src/gui/text/qfontdatabase.cpp60
-rw-r--r--src/gui/text/qfontdatabase.h4
-rw-r--r--src/gui/text/qfontengine.cpp9
-rw-r--r--src/gui/text/qfontengine_p.h28
-rw-r--r--src/gui/text/qfontmetrics.cpp31
-rw-r--r--src/gui/text/qfontmetrics.h37
-rw-r--r--src/gui/text/qfragmentmap_p.h2
-rw-r--r--src/gui/text/qglyphrun.h4
-rw-r--r--src/gui/text/qglyphrun_p.h2
-rw-r--r--src/gui/text/qharfbuzzng.cpp6
-rw-r--r--src/gui/text/qrawfont.cpp2
-rw-r--r--src/gui/text/qrawfont.h6
-rw-r--r--src/gui/text/qrawfont_p.h22
-rw-r--r--src/gui/text/qstatictext.cpp2
-rw-r--r--src/gui/text/qstatictext.h6
-rw-r--r--src/gui/text/qstatictext_p.h4
-rw-r--r--src/gui/text/qsyntaxhighlighter.cpp20
-rw-r--r--src/gui/text/qtextcursor.cpp29
-rw-r--r--src/gui/text/qtextcursor.h4
-rw-r--r--src/gui/text/qtextdocument.cpp14
-rw-r--r--src/gui/text/qtextdocument.h2
-rw-r--r--src/gui/text/qtextdocument_p.cpp18
-rw-r--r--src/gui/text/qtextdocument_p.h6
-rw-r--r--src/gui/text/qtextdocumentfragment.cpp10
-rw-r--r--src/gui/text/qtextdocumentfragment_p.h8
-rw-r--r--src/gui/text/qtextdocumentlayout.cpp104
-rw-r--r--src/gui/text/qtextdocumentwriter.cpp24
-rw-r--r--src/gui/text/qtextdocumentwriter.h2
-rw-r--r--src/gui/text/qtextengine.cpp126
-rw-r--r--src/gui/text/qtextengine_p.h18
-rw-r--r--src/gui/text/qtextformat.cpp55
-rw-r--r--src/gui/text/qtextformat.h16
-rw-r--r--src/gui/text/qtextformat_p.h2
-rw-r--r--src/gui/text/qtexthtmlparser.cpp8
-rw-r--r--src/gui/text/qtextimagehandler_p.h2
-rw-r--r--src/gui/text/qtextlayout.cpp85
-rw-r--r--src/gui/text/qtextlayout.h14
-rw-r--r--src/gui/text/qtextlist.cpp2
-rw-r--r--src/gui/text/qtextlist.h3
-rw-r--r--src/gui/text/qtextobject.cpp18
-rw-r--r--src/gui/text/qtextobject.h8
-rw-r--r--src/gui/text/qtextobject_p.h2
-rw-r--r--src/gui/text/qtextodfwriter.cpp32
-rw-r--r--src/gui/text/qtexttable.cpp12
-rw-r--r--src/gui/text/qtexttable_p.h2
-rw-r--r--src/gui/text/qzipreader_p.h6
-rw-r--r--src/gui/text/qzipwriter_p.h2
57 files changed, 1241 insertions, 765 deletions
diff --git a/src/gui/text/qabstracttextdocumentlayout.h b/src/gui/text/qabstracttextdocumentlayout.h
index 8fea27f772..3371401420 100644
--- a/src/gui/text/qabstracttextdocumentlayout.h
+++ b/src/gui/text/qabstracttextdocumentlayout.h
@@ -143,7 +143,9 @@ public:
virtual void drawObject(QPainter *painter, const QRectF &rect, QTextDocument *doc, int posInDocument, const QTextFormat &format) = 0;
};
+#ifndef Q_CLANG_QDOC
Q_DECLARE_INTERFACE(QTextObjectInterface, "org.qt-project.Qt.QTextObjectInterface")
+#endif
QT_END_NAMESPACE
diff --git a/src/gui/text/qabstracttextdocumentlayout_p.h b/src/gui/text/qabstracttextdocumentlayout_p.h
index 191c463dc6..d631ce3197 100644
--- a/src/gui/text/qabstracttextdocumentlayout_p.h
+++ b/src/gui/text/qabstracttextdocumentlayout_p.h
@@ -59,7 +59,7 @@ QT_BEGIN_NAMESPACE
struct QTextObjectHandler
{
- QTextObjectHandler() : iface(0) {}
+ QTextObjectHandler() : iface(nullptr) {}
QTextObjectInterface *iface;
QPointer<QObject> component;
};
@@ -71,12 +71,12 @@ public:
Q_DECLARE_PUBLIC(QAbstractTextDocumentLayout)
inline QAbstractTextDocumentLayoutPrivate()
- : paintDevice(0) {}
+ : paintDevice(nullptr) {}
~QAbstractTextDocumentLayoutPrivate();
inline void setDocument(QTextDocument *doc) {
document = doc;
- docPrivate = 0;
+ docPrivate = nullptr;
if (doc)
docPrivate = doc->docHandle();
}
diff --git a/src/gui/text/qcssparser.cpp b/src/gui/text/qcssparser.cpp
index 1c454b0fca..dc7e128bcd 100644
--- a/src/gui/text/qcssparser.cpp
+++ b/src/gui/text/qcssparser.cpp
@@ -1200,11 +1200,13 @@ static bool setFontWeightFromValue(const QCss::Value &value, QFont *font)
static bool setFontFamilyFromValues(const QVector<QCss::Value> &values, QFont *font, int start = 0)
{
QString family;
+ QStringList families;
bool shouldAddSpace = false;
for (int i = start; i < values.count(); ++i) {
const QCss::Value &v = values.at(i);
if (v.type == Value::TermOperatorComma) {
- family += QLatin1Char(',');
+ families << family;
+ family.clear();
shouldAddSpace = false;
continue;
}
@@ -1216,9 +1218,12 @@ static bool setFontFamilyFromValues(const QVector<QCss::Value> &values, QFont *f
family += str;
shouldAddSpace = true;
}
- if (family.isEmpty())
+ if (!family.isEmpty())
+ families << family;
+ if (families.isEmpty())
return false;
- font->setFamily(family);
+ font->setFamily(families.at(0));
+ font->setFamilies(families);
return true;
}
@@ -2003,7 +2008,7 @@ bool StyleSelector::basicSelectorMatches(const BasicSelector &sel, NodePtr node)
}
void StyleSelector::matchRule(NodePtr node, const StyleRule &rule, StyleSheetOrigin origin,
- int depth, QMap<uint, StyleRule> *weightedRules)
+ int depth, QMultiMap<uint, StyleRule> *weightedRules)
{
for (int j = 0; j < rule.selectors.count(); ++j) {
const Selector& selector = rule.selectors.at(j);
@@ -2017,7 +2022,7 @@ void StyleSelector::matchRule(NodePtr node, const StyleRule &rule, StyleSheetOri
newRule.selectors[0] = selector;
}
//We might have rules with the same weight if they came from a rule with several selectors
- weightedRules->insertMulti(weight, newRule);
+ weightedRules->insert(weight, newRule);
}
}
}
@@ -2030,7 +2035,7 @@ QVector<StyleRule> StyleSelector::styleRulesForNode(NodePtr node)
if (styleSheets.isEmpty())
return rules;
- QMap<uint, StyleRule> weightedRules; // (spec, rule) that will be sorted below
+ QMultiMap<uint, StyleRule> weightedRules; // (spec, rule) that will be sorted below
//prune using indexed stylesheet
for (int sheetIdx = 0; sheetIdx < styleSheets.count(); ++sheetIdx) {
@@ -2742,8 +2747,10 @@ bool Parser::parseFunction(QString *name, QString *args)
{
*name = lexem();
name->chop(1);
+ // until(RPAREN) needs FUNCTION token at index-1 to work properly
+ int start = index;
skipSpace();
- const int start = index;
+ std::swap(start, index);
if (!until(RPAREN)) return false;
for (int i = start; i < index - 1; ++i)
args->append(symbols.at(i).lexem());
diff --git a/src/gui/text/qcssparser_p.h b/src/gui/text/qcssparser_p.h
index 8f992f8c59..62578f75e5 100644
--- a/src/gui/text/qcssparser_p.h
+++ b/src/gui/text/qcssparser_p.h
@@ -467,8 +467,8 @@ struct Q_GUI_EXPORT Declaration
Attachment attachmentValue() const;
int styleFeaturesValue() const;
- bool intValue(int *i, const char *unit = 0) const;
- bool realValue(qreal *r, const char *unit = 0) const;
+ bool intValue(int *i, const char *unit = nullptr) const;
+ bool realValue(qreal *r, const char *unit = nullptr) const;
QSize sizeValue() const;
QRect rectValue() const;
@@ -584,7 +584,7 @@ struct Q_GUI_EXPORT Selector
{
QVector<BasicSelector> basicSelectors;
int specificity() const;
- quint64 pseudoClass(quint64 *negated = 0) const;
+ quint64 pseudoClass(quint64 *negated = nullptr) const;
QString pseudoElement() const;
};
QT_CSS_DECLARE_TYPEINFO(Selector, Q_MOVABLE_TYPE)
@@ -656,7 +656,7 @@ public:
};
QVector<StyleRule> styleRulesForNode(NodePtr node);
- QVector<Declaration> declarationsForNode(NodePtr node, const char *extraPseudo = 0);
+ QVector<Declaration> declarationsForNode(NodePtr node, const char *extraPseudo = nullptr);
virtual bool nodeNameEquals(NodePtr node, const QString& nodeName) const;
virtual QString attribute(NodePtr node, const QString &name) const = 0;
@@ -674,7 +674,7 @@ public:
Qt::CaseSensitivity nameCaseSensitivity;
private:
void matchRule(NodePtr node, const StyleRule &rules, StyleSheetOrigin origin,
- int depth, QMap<uint, StyleRule> *weightedRules);
+ int depth, QMultiMap<uint, StyleRule> *weightedRules);
bool selectorMatches(const Selector &rule, NodePtr node);
bool basicSelectorMatches(const BasicSelector &rule, NodePtr node);
};
@@ -744,7 +744,7 @@ QT_CSS_DECLARE_TYPEINFO(Symbol, Q_MOVABLE_TYPE)
class Q_GUI_EXPORT Scanner
{
public:
- static QString preprocess(const QString &input, bool *hasEscapeSequences = 0);
+ static QString preprocess(const QString &input, bool *hasEscapeSequences = nullptr);
static void scan(const QString &preprocessedInput, QVector<Symbol> *symbols);
};
@@ -845,7 +845,7 @@ struct Q_GUI_EXPORT ValueExtractor
bool extractGeometry(int *w, int *h, int *minw, int *minh, int *maxw, int *maxh);
bool extractPosition(int *l, int *t, int *r, int *b, QCss::Origin *, Qt::Alignment *,
QCss::PositionMode *, Qt::Alignment *);
- bool extractBox(int *margins, int *paddings, int *spacing = 0);
+ bool extractBox(int *margins, int *paddings, int *spacing = nullptr);
bool extractBorder(int *borders, QBrush *colors, BorderStyle *Styles, QSize *radii);
bool extractOutline(int *borders, QBrush *colors, BorderStyle *Styles, QSize *radii, int *offsets);
bool extractPalette(QBrush *fg, QBrush *sfg, QBrush *sbg, QBrush *abg);
diff --git a/src/gui/text/qcssscanner.cpp b/src/gui/text/qcssscanner.cpp
index 33dc01c8bc..d48cbb71d7 100644
--- a/src/gui/text/qcssscanner.cpp
+++ b/src/gui/text/qcssscanner.cpp
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2016 The Qt Company Ltd.
+** Copyright (C) 2018 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the QtGui module of the Qt Toolkit.
@@ -37,7 +37,7 @@
**
****************************************************************************/
-// auto generated. DO NOT EDIT.
+// auto generated by qtbase/util/lexgen/. DO NOT EDIT.
class QCssScanner_Generated
{
public:
@@ -75,23 +75,23 @@ int QCssScanner_Generated::lex()
// initial state
ch = next();
if (ch.unicode() >= 9 && ch.unicode() <= 10)
- goto state_1;
+ goto state_4;
if (ch.unicode() >= 12 && ch.unicode() <= 13)
- goto state_1;
+ goto state_4;
if (ch.unicode() == 32)
- goto state_1;
+ goto state_4;
if (ch.unicode() == 33) {
token = QCss::EXCLAMATION_SYM;
goto found;
}
if (ch.unicode() == 34)
- goto state_3;
+ goto state_2;
if (ch.unicode() == 35)
- goto state_4;
+ goto state_1;
if (ch.unicode() == 36)
- goto state_5;
- if (ch.unicode() == 39)
goto state_6;
+ if (ch.unicode() == 39)
+ goto state_5;
if (ch.unicode() == 40) {
token = QCss::LPAREN;
goto found;
@@ -101,17 +101,17 @@ int QCssScanner_Generated::lex()
goto found;
}
if (ch.unicode() == 42)
- goto state_9;
+ goto state_8;
if (ch.unicode() == 43)
- goto state_10;
+ goto state_7;
if (ch.unicode() == 44)
- goto state_11;
+ goto state_14;
if (ch.unicode() == 45)
- goto state_12;
- if (ch.unicode() == 46)
goto state_13;
+ if (ch.unicode() == 46)
+ goto state_12;
if (ch.unicode() == 47)
- goto state_14;
+ goto state_11;
if (ch.unicode() >= 48 && ch.unicode() <= 57)
goto state_15;
if (ch.unicode() == 58) {
@@ -123,64 +123,56 @@ int QCssScanner_Generated::lex()
goto found;
}
if (ch.unicode() == 60)
- goto state_18;
+ goto state_20;
if (ch.unicode() == 61) {
token = QCss::EQUAL;
goto found;
}
if (ch.unicode() == 62)
- goto state_20;
+ goto state_18;
if (ch.unicode() == 64)
- goto state_21;
+ goto state_26;
if (ch.unicode() == 91) {
token = QCss::LBRACKET;
goto found;
}
if (ch.unicode() == 92)
- goto state_23;
+ goto state_30;
if (ch.unicode() == 93) {
token = QCss::RBRACKET;
goto found;
}
if (ch.unicode() == 94)
- goto state_25;
+ goto state_28;
if (ch.unicode() == 95)
- goto state_26;
+ goto state_21;
if ((ch.unicode() >= 'a' && ch.unicode() <= 'z') || (ch.unicode() >= 'A' && ch.unicode() <= 'Z') || ch.unicode() >= 256)
- goto state_26;
+ goto state_21;
if (ch.unicode() == 123)
- goto state_27;
+ goto state_22;
if (ch.unicode() == 124)
- goto state_28;
+ goto state_25;
if (ch.unicode() == 125) {
token = QCss::RBRACE;
goto found;
}
if (ch.unicode() == 126)
- goto state_30;
+ goto state_23;
goto out;
state_1:
- lastAcceptingPos = pos;
- token = QCss::S;
ch = next();
- if (ch.unicode() >= 9 && ch.unicode() <= 10)
- goto state_31;
- if (ch.unicode() >= 12 && ch.unicode() <= 13)
+ if (ch.unicode() == 45)
goto state_31;
- if (ch.unicode() == 32)
+ if (ch.unicode() >= 48 && ch.unicode() <= 57)
goto state_31;
- if (ch.unicode() == 43)
- goto state_10;
- if (ch.unicode() == 44)
- goto state_11;
- if (ch.unicode() == 62)
- goto state_20;
- if (ch.unicode() == 123)
- goto state_27;
- if (ch.unicode() == 126)
+ if (ch.unicode() == 92)
goto state_32;
+ if (ch.unicode() == 95)
+ goto state_31;
+ if ((ch.unicode() >= 'a' && ch.unicode() <= 'z') || (ch.unicode() >= 'A' && ch.unicode() <= 'Z') || ch.unicode() >= 256)
+ goto state_31;
goto out;
- state_3:
+ state_2:
lastAcceptingPos = pos;
token = QCss::INVALID;
ch = next();
@@ -204,93 +196,101 @@ int QCssScanner_Generated::lex()
goto state_33;
goto out;
state_4:
+ lastAcceptingPos = pos;
+ token = QCss::S;
ch = next();
- if (ch.unicode() == 45)
- goto state_36;
- if (ch.unicode() >= 48 && ch.unicode() <= 57)
+ if (ch.unicode() >= 9 && ch.unicode() <= 10)
goto state_36;
- if (ch.unicode() == 92)
- goto state_37;
- if (ch.unicode() == 95)
+ if (ch.unicode() >= 12 && ch.unicode() <= 13)
goto state_36;
- if ((ch.unicode() >= 'a' && ch.unicode() <= 'z') || (ch.unicode() >= 'A' && ch.unicode() <= 'Z') || ch.unicode() >= 256)
+ if (ch.unicode() == 32)
goto state_36;
+ if (ch.unicode() == 43)
+ goto state_7;
+ if (ch.unicode() == 44)
+ goto state_14;
+ if (ch.unicode() == 62)
+ goto state_18;
+ if (ch.unicode() == 123)
+ goto state_22;
+ if (ch.unicode() == 126)
+ goto state_37;
goto out;
state_5:
- ch = next();
- if (ch.unicode() == 61) {
- token = QCss::ENDSWITH;
- goto found;
- }
- goto out;
- state_6:
lastAcceptingPos = pos;
token = QCss::INVALID;
ch = next();
if (ch.unicode() >= 1 && ch.unicode() <= 9)
- goto state_39;
+ goto state_38;
if (ch.unicode() == 11)
- goto state_39;
+ goto state_38;
if (ch.unicode() >= 14 && ch.unicode() <= 38)
- goto state_39;
+ goto state_38;
if (ch.unicode() == 39)
- goto state_40;
- if (ch.unicode() >= 40 && ch.unicode() <= 91)
goto state_39;
+ if (ch.unicode() >= 40 && ch.unicode() <= 91)
+ goto state_38;
if (ch.unicode() == 92)
- goto state_41;
+ goto state_40;
if (ch.unicode() >= 93 && ch.unicode() <= 96)
- goto state_39;
+ goto state_38;
if ((ch.unicode() >= 'a' && ch.unicode() <= 'z') || (ch.unicode() >= 'A' && ch.unicode() <= 'Z') || ch.unicode() >= 256)
- goto state_39;
+ goto state_38;
if (ch.unicode() >= 123)
- goto state_39;
+ goto state_38;
goto out;
- state_9:
- lastAcceptingPos = pos;
- token = QCss::STAR;
+ state_6:
ch = next();
if (ch.unicode() == 61) {
- token = QCss::CONTAINS;
+ token = QCss::ENDSWITH;
goto found;
}
goto out;
- state_10:
+ state_7:
lastAcceptingPos = pos;
token = QCss::PLUS;
goto out;
+ state_8:
+ lastAcceptingPos = pos;
+ token = QCss::STAR;
+ ch = next();
+ if (ch.unicode() == 61) {
+ token = QCss::CONTAINS;
+ goto found;
+ }
+ goto out;
state_11:
lastAcceptingPos = pos;
- token = QCss::COMMA;
+ token = QCss::SLASH;
+ ch = next();
+ if (ch.unicode() == 42) {
+ token = handleCommentStart();
+ goto found;
+ }
goto out;
state_12:
lastAcceptingPos = pos;
+ token = QCss::DOT;
+ ch = next();
+ if (ch.unicode() >= 48 && ch.unicode() <= 57)
+ goto state_44;
+ goto out;
+ state_13:
+ lastAcceptingPos = pos;
token = QCss::MINUS;
ch = next();
if (ch.unicode() == 45)
- goto state_43;
+ goto state_45;
if (ch.unicode() == 92)
- goto state_23;
+ goto state_30;
if (ch.unicode() == 95)
- goto state_26;
+ goto state_21;
if ((ch.unicode() >= 'a' && ch.unicode() <= 'z') || (ch.unicode() >= 'A' && ch.unicode() <= 'Z') || ch.unicode() >= 256)
- goto state_26;
- goto out;
- state_13:
- lastAcceptingPos = pos;
- token = QCss::DOT;
- ch = next();
- if (ch.unicode() >= 48 && ch.unicode() <= 57)
- goto state_44;
+ goto state_21;
goto out;
state_14:
lastAcceptingPos = pos;
- token = QCss::SLASH;
- ch = next();
- if (ch.unicode() == 42) {
- token = handleCommentStart();
- goto found;
- }
+ token = QCss::COMMA;
goto out;
state_15:
lastAcceptingPos = pos;
@@ -299,68 +299,70 @@ int QCssScanner_Generated::lex()
if (ch.unicode() == 37)
goto state_46;
if (ch.unicode() == 45)
- goto state_47;
- if (ch.unicode() == 46)
goto state_48;
+ if (ch.unicode() == 46)
+ goto state_47;
if (ch.unicode() >= 48 && ch.unicode() <= 57)
goto state_49;
if (ch.unicode() == 92)
- goto state_50;
- if (ch.unicode() == 95)
goto state_51;
+ if (ch.unicode() == 95)
+ goto state_50;
if ((ch.unicode() >= 'a' && ch.unicode() <= 'z') || (ch.unicode() >= 'A' && ch.unicode() <= 'Z') || ch.unicode() >= 256)
- goto state_51;
+ goto state_50;
goto out;
state_18:
+ lastAcceptingPos = pos;
+ token = QCss::GREATER;
+ goto out;
+ state_20:
ch = next();
if (ch.unicode() == 33)
goto state_52;
goto out;
- state_20:
- lastAcceptingPos = pos;
- token = QCss::GREATER;
- goto out;
state_21:
+ lastAcceptingPos = pos;
+ token = QCss::IDENT;
ch = next();
- if (ch.unicode() == 45)
+ if (ch.unicode() == 40)
goto state_53;
- if (ch.unicode() == 92)
+ if (ch.unicode() == 45)
goto state_54;
- if (ch.unicode() == 95)
+ if (ch.unicode() >= 48 && ch.unicode() <= 57)
+ goto state_54;
+ if (ch.unicode() == 92)
goto state_55;
+ if (ch.unicode() == 95)
+ goto state_54;
if ((ch.unicode() >= 'a' && ch.unicode() <= 'z') || (ch.unicode() >= 'A' && ch.unicode() <= 'Z') || ch.unicode() >= 256)
- goto state_55;
+ goto state_54;
+ goto out;
+ state_22:
+ lastAcceptingPos = pos;
+ token = QCss::LBRACE;
goto out;
state_23:
+ lastAcceptingPos = pos;
+ token = QCss::TILDE;
ch = next();
- if (ch.unicode() >= 1 && ch.unicode() <= 9)
- goto state_56;
- if (ch.unicode() == 11)
- goto state_56;
- if (ch.unicode() >= 14 && ch.unicode() <= 47)
- goto state_56;
- if (ch.unicode() >= 58 && ch.unicode() <= 96)
- goto state_56;
- if (ch.unicode() >= 103)
- goto state_56;
+ if (ch.unicode() == 61) {
+ token = QCss::INCLUDES;
+ goto found;
+ }
goto out;
state_25:
+ lastAcceptingPos = pos;
+ token = QCss::OR;
ch = next();
if (ch.unicode() == 61) {
- token = QCss::BEGINSWITH;
+ token = QCss::DASHMATCH;
goto found;
}
goto out;
state_26:
- lastAcceptingPos = pos;
- token = QCss::IDENT;
ch = next();
- if (ch.unicode() == 40)
- goto state_58;
if (ch.unicode() == 45)
- goto state_59;
- if (ch.unicode() >= 48 && ch.unicode() <= 57)
- goto state_59;
+ goto state_58;
if (ch.unicode() == 92)
goto state_60;
if (ch.unicode() == 95)
@@ -368,52 +370,53 @@ int QCssScanner_Generated::lex()
if ((ch.unicode() >= 'a' && ch.unicode() <= 'z') || (ch.unicode() >= 'A' && ch.unicode() <= 'Z') || ch.unicode() >= 256)
goto state_59;
goto out;
- state_27:
- lastAcceptingPos = pos;
- token = QCss::LBRACE;
- goto out;
state_28:
- lastAcceptingPos = pos;
- token = QCss::OR;
ch = next();
if (ch.unicode() == 61) {
- token = QCss::DASHMATCH;
+ token = QCss::BEGINSWITH;
goto found;
}
goto out;
state_30:
- lastAcceptingPos = pos;
- token = QCss::TILDE;
ch = next();
- if (ch.unicode() == 61) {
- token = QCss::INCLUDES;
- goto found;
- }
+ if (ch.unicode() >= 1 && ch.unicode() <= 9)
+ goto state_62;
+ if (ch.unicode() == 11)
+ goto state_62;
+ if (ch.unicode() >= 14 && ch.unicode() <= 47)
+ goto state_62;
+ if (ch.unicode() >= 58 && ch.unicode() <= 96)
+ goto state_62;
+ if (ch.unicode() >= 103)
+ goto state_62;
goto out;
state_31:
lastAcceptingPos = pos;
- token = QCss::S;
+ token = QCss::HASH;
ch = next();
- if (ch.unicode() >= 9 && ch.unicode() <= 10)
- goto state_31;
- if (ch.unicode() >= 12 && ch.unicode() <= 13)
- goto state_31;
- if (ch.unicode() == 32)
- goto state_31;
- if (ch.unicode() == 43)
- goto state_10;
- if (ch.unicode() == 44)
- goto state_11;
- if (ch.unicode() == 62)
- goto state_20;
- if (ch.unicode() == 123)
- goto state_27;
- if (ch.unicode() == 126)
- goto state_32;
+ if (ch.unicode() == 45)
+ goto state_63;
+ if (ch.unicode() >= 48 && ch.unicode() <= 57)
+ goto state_63;
+ if (ch.unicode() == 92)
+ goto state_64;
+ if (ch.unicode() == 95)
+ goto state_63;
+ if ((ch.unicode() >= 'a' && ch.unicode() <= 'z') || (ch.unicode() >= 'A' && ch.unicode() <= 'Z') || ch.unicode() >= 256)
+ goto state_63;
goto out;
state_32:
- lastAcceptingPos = pos;
- token = QCss::TILDE;
+ ch = next();
+ if (ch.unicode() >= 1 && ch.unicode() <= 9)
+ goto state_65;
+ if (ch.unicode() == 11)
+ goto state_65;
+ if (ch.unicode() >= 14 && ch.unicode() <= 47)
+ goto state_65;
+ if (ch.unicode() >= 58 && ch.unicode() <= 96)
+ goto state_65;
+ if (ch.unicode() >= 103)
+ goto state_65;
goto out;
state_33:
lastAcceptingPos = pos;
@@ -445,78 +448,75 @@ int QCssScanner_Generated::lex()
state_35:
ch = next();
if (ch.unicode() >= 1 && ch.unicode() <= 9)
- goto state_63;
+ goto state_66;
if (ch.unicode() == 10)
- goto state_64;
+ goto state_67;
if (ch.unicode() == 11)
- goto state_63;
+ goto state_66;
if (ch.unicode() == 12)
- goto state_65;
+ goto state_69;
if (ch.unicode() == 13)
- goto state_66;
+ goto state_68;
if (ch.unicode() >= 14 && ch.unicode() <= 47)
- goto state_63;
+ goto state_66;
if (ch.unicode() >= 58 && ch.unicode() <= 96)
- goto state_63;
+ goto state_66;
if (ch.unicode() >= 103)
- goto state_63;
+ goto state_66;
goto out;
state_36:
lastAcceptingPos = pos;
- token = QCss::HASH;
+ token = QCss::S;
ch = next();
- if (ch.unicode() == 45)
- goto state_67;
- if (ch.unicode() >= 48 && ch.unicode() <= 57)
- goto state_67;
- if (ch.unicode() == 92)
- goto state_68;
- if (ch.unicode() == 95)
- goto state_67;
- if ((ch.unicode() >= 'a' && ch.unicode() <= 'z') || (ch.unicode() >= 'A' && ch.unicode() <= 'Z') || ch.unicode() >= 256)
- goto state_67;
+ if (ch.unicode() >= 9 && ch.unicode() <= 10)
+ goto state_36;
+ if (ch.unicode() >= 12 && ch.unicode() <= 13)
+ goto state_36;
+ if (ch.unicode() == 32)
+ goto state_36;
+ if (ch.unicode() == 43)
+ goto state_7;
+ if (ch.unicode() == 44)
+ goto state_14;
+ if (ch.unicode() == 62)
+ goto state_18;
+ if (ch.unicode() == 123)
+ goto state_22;
+ if (ch.unicode() == 126)
+ goto state_37;
goto out;
state_37:
- ch = next();
- if (ch.unicode() >= 1 && ch.unicode() <= 9)
- goto state_69;
- if (ch.unicode() == 11)
- goto state_69;
- if (ch.unicode() >= 14 && ch.unicode() <= 47)
- goto state_69;
- if (ch.unicode() >= 58 && ch.unicode() <= 96)
- goto state_69;
- if (ch.unicode() >= 103)
- goto state_69;
+ lastAcceptingPos = pos;
+ token = QCss::TILDE;
goto out;
- state_39:
+ state_38:
lastAcceptingPos = pos;
token = QCss::INVALID;
ch = next();
if (ch.unicode() >= 1 && ch.unicode() <= 9)
- goto state_39;
+ goto state_38;
if (ch.unicode() == 11)
- goto state_39;
+ goto state_38;
if (ch.unicode() >= 14 && ch.unicode() <= 38)
- goto state_39;
+ goto state_38;
if (ch.unicode() == 39)
- goto state_40;
- if (ch.unicode() >= 40 && ch.unicode() <= 91)
goto state_39;
+ if (ch.unicode() >= 40 && ch.unicode() <= 91)
+ goto state_38;
if (ch.unicode() == 92)
- goto state_41;
+ goto state_40;
if (ch.unicode() >= 93 && ch.unicode() <= 96)
- goto state_39;
+ goto state_38;
if ((ch.unicode() >= 'a' && ch.unicode() <= 'z') || (ch.unicode() >= 'A' && ch.unicode() <= 'Z') || ch.unicode() >= 256)
- goto state_39;
+ goto state_38;
if (ch.unicode() >= 123)
- goto state_39;
+ goto state_38;
goto out;
- state_40:
+ state_39:
lastAcceptingPos = pos;
token = QCss::STRING;
goto out;
- state_41:
+ state_40:
ch = next();
if (ch.unicode() >= 1 && ch.unicode() <= 9)
goto state_70;
@@ -525,9 +525,9 @@ int QCssScanner_Generated::lex()
if (ch.unicode() == 11)
goto state_70;
if (ch.unicode() == 12)
- goto state_72;
- if (ch.unicode() == 13)
goto state_73;
+ if (ch.unicode() == 13)
+ goto state_72;
if (ch.unicode() >= 14 && ch.unicode() <= 47)
goto state_70;
if (ch.unicode() >= 58 && ch.unicode() <= 96)
@@ -535,13 +535,6 @@ int QCssScanner_Generated::lex()
if (ch.unicode() >= 103)
goto state_70;
goto out;
- state_43:
- ch = next();
- if (ch.unicode() == 62) {
- token = QCss::CDC;
- goto found;
- }
- goto out;
state_44:
lastAcceptingPos = pos;
token = QCss::NUMBER;
@@ -549,15 +542,22 @@ int QCssScanner_Generated::lex()
if (ch.unicode() == 37)
goto state_46;
if (ch.unicode() == 45)
- goto state_47;
+ goto state_48;
if (ch.unicode() >= 48 && ch.unicode() <= 57)
- goto state_75;
+ goto state_74;
if (ch.unicode() == 92)
- goto state_50;
- if (ch.unicode() == 95)
goto state_51;
+ if (ch.unicode() == 95)
+ goto state_50;
if ((ch.unicode() >= 'a' && ch.unicode() <= 'z') || (ch.unicode() >= 'A' && ch.unicode() <= 'Z') || ch.unicode() >= 256)
- goto state_51;
+ goto state_50;
+ goto out;
+ state_45:
+ ch = next();
+ if (ch.unicode() == 62) {
+ token = QCss::CDC;
+ goto found;
+ }
goto out;
state_46:
lastAcceptingPos = pos;
@@ -565,17 +565,17 @@ int QCssScanner_Generated::lex()
goto out;
state_47:
ch = next();
- if (ch.unicode() == 92)
- goto state_50;
- if (ch.unicode() == 95)
- goto state_51;
- if ((ch.unicode() >= 'a' && ch.unicode() <= 'z') || (ch.unicode() >= 'A' && ch.unicode() <= 'Z') || ch.unicode() >= 256)
- goto state_51;
+ if (ch.unicode() >= 48 && ch.unicode() <= 57)
+ goto state_44;
goto out;
state_48:
ch = next();
- if (ch.unicode() >= 48 && ch.unicode() <= 57)
- goto state_44;
+ if (ch.unicode() == 92)
+ goto state_51;
+ if (ch.unicode() == 95)
+ goto state_50;
+ if ((ch.unicode() >= 'a' && ch.unicode() <= 'z') || (ch.unicode() >= 'A' && ch.unicode() <= 'Z') || ch.unicode() >= 256)
+ goto state_50;
goto out;
state_49:
lastAcceptingPos = pos;
@@ -584,45 +584,45 @@ int QCssScanner_Generated::lex()
if (ch.unicode() == 37)
goto state_46;
if (ch.unicode() == 45)
- goto state_47;
- if (ch.unicode() == 46)
goto state_48;
+ if (ch.unicode() == 46)
+ goto state_47;
if (ch.unicode() >= 48 && ch.unicode() <= 57)
goto state_49;
if (ch.unicode() == 92)
- goto state_50;
- if (ch.unicode() == 95)
goto state_51;
+ if (ch.unicode() == 95)
+ goto state_50;
if ((ch.unicode() >= 'a' && ch.unicode() <= 'z') || (ch.unicode() >= 'A' && ch.unicode() <= 'Z') || ch.unicode() >= 256)
- goto state_51;
+ goto state_50;
goto out;
state_50:
+ lastAcceptingPos = pos;
+ token = QCss::LENGTH;
ch = next();
- if (ch.unicode() >= 1 && ch.unicode() <= 9)
- goto state_76;
- if (ch.unicode() == 11)
+ if (ch.unicode() == 45)
goto state_76;
- if (ch.unicode() >= 14 && ch.unicode() <= 47)
+ if (ch.unicode() >= 48 && ch.unicode() <= 57)
goto state_76;
- if (ch.unicode() >= 58 && ch.unicode() <= 96)
+ if (ch.unicode() == 92)
+ goto state_77;
+ if (ch.unicode() == 95)
goto state_76;
- if (ch.unicode() >= 103)
+ if ((ch.unicode() >= 'a' && ch.unicode() <= 'z') || (ch.unicode() >= 'A' && ch.unicode() <= 'Z') || ch.unicode() >= 256)
goto state_76;
goto out;
state_51:
- lastAcceptingPos = pos;
- token = QCss::LENGTH;
ch = next();
- if (ch.unicode() == 45)
- goto state_77;
- if (ch.unicode() >= 48 && ch.unicode() <= 57)
- goto state_77;
- if (ch.unicode() == 92)
+ if (ch.unicode() >= 1 && ch.unicode() <= 9)
+ goto state_78;
+ if (ch.unicode() == 11)
+ goto state_78;
+ if (ch.unicode() >= 14 && ch.unicode() <= 47)
+ goto state_78;
+ if (ch.unicode() >= 58 && ch.unicode() <= 96)
+ goto state_78;
+ if (ch.unicode() >= 103)
goto state_78;
- if (ch.unicode() == 95)
- goto state_77;
- if ((ch.unicode() >= 'a' && ch.unicode() <= 'z') || (ch.unicode() >= 'A' && ch.unicode() <= 'Z') || ch.unicode() >= 256)
- goto state_77;
goto out;
state_52:
ch = next();
@@ -630,15 +630,27 @@ int QCssScanner_Generated::lex()
goto state_79;
goto out;
state_53:
+ lastAcceptingPos = pos;
+ token = QCss::FUNCTION;
+ goto out;
+ state_54:
+ lastAcceptingPos = pos;
+ token = QCss::IDENT;
ch = next();
- if (ch.unicode() == 92)
+ if (ch.unicode() == 40)
+ goto state_53;
+ if (ch.unicode() == 45)
goto state_54;
- if (ch.unicode() == 95)
+ if (ch.unicode() >= 48 && ch.unicode() <= 57)
+ goto state_54;
+ if (ch.unicode() == 92)
goto state_55;
+ if (ch.unicode() == 95)
+ goto state_54;
if ((ch.unicode() >= 'a' && ch.unicode() <= 'z') || (ch.unicode() >= 'A' && ch.unicode() <= 'Z') || ch.unicode() >= 256)
- goto state_55;
+ goto state_54;
goto out;
- state_54:
+ state_55:
ch = next();
if (ch.unicode() >= 1 && ch.unicode() <= 9)
goto state_80;
@@ -651,7 +663,16 @@ int QCssScanner_Generated::lex()
if (ch.unicode() >= 103)
goto state_80;
goto out;
- state_55:
+ state_58:
+ ch = next();
+ if (ch.unicode() == 92)
+ goto state_60;
+ if (ch.unicode() == 95)
+ goto state_59;
+ if ((ch.unicode() >= 'a' && ch.unicode() <= 'z') || (ch.unicode() >= 'A' && ch.unicode() <= 'Z') || ch.unicode() >= 256)
+ goto state_59;
+ goto out;
+ state_59:
lastAcceptingPos = pos;
token = QCss::ATKEYWORD_SYM;
ch = next();
@@ -666,58 +687,80 @@ int QCssScanner_Generated::lex()
if ((ch.unicode() >= 'a' && ch.unicode() <= 'z') || (ch.unicode() >= 'A' && ch.unicode() <= 'Z') || ch.unicode() >= 256)
goto state_81;
goto out;
- state_56:
+ state_60:
+ ch = next();
+ if (ch.unicode() >= 1 && ch.unicode() <= 9)
+ goto state_83;
+ if (ch.unicode() == 11)
+ goto state_83;
+ if (ch.unicode() >= 14 && ch.unicode() <= 47)
+ goto state_83;
+ if (ch.unicode() >= 58 && ch.unicode() <= 96)
+ goto state_83;
+ if (ch.unicode() >= 103)
+ goto state_83;
+ goto out;
+ state_62:
lastAcceptingPos = pos;
token = QCss::IDENT;
ch = next();
if (ch.unicode() == 40)
- goto state_58;
+ goto state_53;
if (ch.unicode() == 45)
- goto state_59;
+ goto state_54;
if (ch.unicode() >= 48 && ch.unicode() <= 57)
- goto state_59;
+ goto state_54;
if (ch.unicode() == 92)
- goto state_60;
+ goto state_55;
if (ch.unicode() == 95)
- goto state_59;
+ goto state_54;
if ((ch.unicode() >= 'a' && ch.unicode() <= 'z') || (ch.unicode() >= 'A' && ch.unicode() <= 'Z') || ch.unicode() >= 256)
- goto state_59;
- goto out;
- state_58:
- lastAcceptingPos = pos;
- token = QCss::FUNCTION;
+ goto state_54;
goto out;
- state_59:
+ state_63:
lastAcceptingPos = pos;
- token = QCss::IDENT;
+ token = QCss::HASH;
ch = next();
- if (ch.unicode() == 40)
- goto state_58;
if (ch.unicode() == 45)
- goto state_59;
+ goto state_63;
if (ch.unicode() >= 48 && ch.unicode() <= 57)
- goto state_59;
+ goto state_63;
if (ch.unicode() == 92)
- goto state_60;
+ goto state_64;
if (ch.unicode() == 95)
- goto state_59;
+ goto state_63;
if ((ch.unicode() >= 'a' && ch.unicode() <= 'z') || (ch.unicode() >= 'A' && ch.unicode() <= 'Z') || ch.unicode() >= 256)
- goto state_59;
+ goto state_63;
goto out;
- state_60:
+ state_64:
ch = next();
if (ch.unicode() >= 1 && ch.unicode() <= 9)
- goto state_83;
+ goto state_84;
if (ch.unicode() == 11)
- goto state_83;
+ goto state_84;
if (ch.unicode() >= 14 && ch.unicode() <= 47)
- goto state_83;
+ goto state_84;
if (ch.unicode() >= 58 && ch.unicode() <= 96)
- goto state_83;
+ goto state_84;
if (ch.unicode() >= 103)
- goto state_83;
+ goto state_84;
goto out;
- state_63:
+ state_65:
+ lastAcceptingPos = pos;
+ token = QCss::HASH;
+ ch = next();
+ if (ch.unicode() == 45)
+ goto state_63;
+ if (ch.unicode() >= 48 && ch.unicode() <= 57)
+ goto state_63;
+ if (ch.unicode() == 92)
+ goto state_64;
+ if (ch.unicode() == 95)
+ goto state_63;
+ if ((ch.unicode() >= 'a' && ch.unicode() <= 'z') || (ch.unicode() >= 'A' && ch.unicode() <= 'Z') || ch.unicode() >= 256)
+ goto state_63;
+ goto out;
+ state_66:
lastAcceptingPos = pos;
token = QCss::INVALID;
ch = next();
@@ -740,7 +783,7 @@ int QCssScanner_Generated::lex()
if (ch.unicode() >= 123)
goto state_33;
goto out;
- state_64:
+ state_67:
lastAcceptingPos = pos;
token = QCss::INVALID;
ch = next();
@@ -763,12 +806,14 @@ int QCssScanner_Generated::lex()
if (ch.unicode() >= 123)
goto state_33;
goto out;
- state_65:
+ state_68:
lastAcceptingPos = pos;
token = QCss::INVALID;
ch = next();
if (ch.unicode() >= 1 && ch.unicode() <= 9)
goto state_33;
+ if (ch.unicode() == 10)
+ goto state_85;
if (ch.unicode() == 11)
goto state_33;
if (ch.unicode() >= 14 && ch.unicode() <= 33)
@@ -786,14 +831,12 @@ int QCssScanner_Generated::lex()
if (ch.unicode() >= 123)
goto state_33;
goto out;
- state_66:
+ state_69:
lastAcceptingPos = pos;
token = QCss::INVALID;
ch = next();
if (ch.unicode() >= 1 && ch.unicode() <= 9)
goto state_33;
- if (ch.unicode() == 10)
- goto state_84;
if (ch.unicode() == 11)
goto state_33;
if (ch.unicode() >= 14 && ch.unicode() <= 33)
@@ -811,191 +854,133 @@ int QCssScanner_Generated::lex()
if (ch.unicode() >= 123)
goto state_33;
goto out;
- state_67:
- lastAcceptingPos = pos;
- token = QCss::HASH;
- ch = next();
- if (ch.unicode() == 45)
- goto state_67;
- if (ch.unicode() >= 48 && ch.unicode() <= 57)
- goto state_67;
- if (ch.unicode() == 92)
- goto state_68;
- if (ch.unicode() == 95)
- goto state_67;
- if ((ch.unicode() >= 'a' && ch.unicode() <= 'z') || (ch.unicode() >= 'A' && ch.unicode() <= 'Z') || ch.unicode() >= 256)
- goto state_67;
- goto out;
- state_68:
- ch = next();
- if (ch.unicode() >= 1 && ch.unicode() <= 9)
- goto state_85;
- if (ch.unicode() == 11)
- goto state_85;
- if (ch.unicode() >= 14 && ch.unicode() <= 47)
- goto state_85;
- if (ch.unicode() >= 58 && ch.unicode() <= 96)
- goto state_85;
- if (ch.unicode() >= 103)
- goto state_85;
- goto out;
- state_69:
- lastAcceptingPos = pos;
- token = QCss::HASH;
- ch = next();
- if (ch.unicode() == 45)
- goto state_67;
- if (ch.unicode() >= 48 && ch.unicode() <= 57)
- goto state_67;
- if (ch.unicode() == 92)
- goto state_68;
- if (ch.unicode() == 95)
- goto state_67;
- if ((ch.unicode() >= 'a' && ch.unicode() <= 'z') || (ch.unicode() >= 'A' && ch.unicode() <= 'Z') || ch.unicode() >= 256)
- goto state_67;
- goto out;
state_70:
lastAcceptingPos = pos;
token = QCss::INVALID;
ch = next();
if (ch.unicode() >= 1 && ch.unicode() <= 9)
- goto state_39;
+ goto state_38;
if (ch.unicode() == 11)
- goto state_39;
+ goto state_38;
if (ch.unicode() >= 14 && ch.unicode() <= 38)
- goto state_39;
+ goto state_38;
if (ch.unicode() == 39)
- goto state_40;
- if (ch.unicode() >= 40 && ch.unicode() <= 91)
goto state_39;
+ if (ch.unicode() >= 40 && ch.unicode() <= 91)
+ goto state_38;
if (ch.unicode() == 92)
- goto state_41;
+ goto state_40;
if (ch.unicode() >= 93 && ch.unicode() <= 96)
- goto state_39;
+ goto state_38;
if ((ch.unicode() >= 'a' && ch.unicode() <= 'z') || (ch.unicode() >= 'A' && ch.unicode() <= 'Z') || ch.unicode() >= 256)
- goto state_39;
+ goto state_38;
if (ch.unicode() >= 123)
- goto state_39;
+ goto state_38;
goto out;
state_71:
lastAcceptingPos = pos;
token = QCss::INVALID;
ch = next();
if (ch.unicode() >= 1 && ch.unicode() <= 9)
- goto state_39;
+ goto state_38;
if (ch.unicode() == 11)
- goto state_39;
+ goto state_38;
if (ch.unicode() >= 14 && ch.unicode() <= 38)
- goto state_39;
+ goto state_38;
if (ch.unicode() == 39)
- goto state_40;
- if (ch.unicode() >= 40 && ch.unicode() <= 91)
goto state_39;
+ if (ch.unicode() >= 40 && ch.unicode() <= 91)
+ goto state_38;
if (ch.unicode() == 92)
- goto state_41;
+ goto state_40;
if (ch.unicode() >= 93 && ch.unicode() <= 96)
- goto state_39;
+ goto state_38;
if ((ch.unicode() >= 'a' && ch.unicode() <= 'z') || (ch.unicode() >= 'A' && ch.unicode() <= 'Z') || ch.unicode() >= 256)
- goto state_39;
+ goto state_38;
if (ch.unicode() >= 123)
- goto state_39;
+ goto state_38;
goto out;
state_72:
lastAcceptingPos = pos;
token = QCss::INVALID;
ch = next();
if (ch.unicode() >= 1 && ch.unicode() <= 9)
- goto state_39;
+ goto state_38;
+ if (ch.unicode() == 10)
+ goto state_86;
if (ch.unicode() == 11)
- goto state_39;
+ goto state_38;
if (ch.unicode() >= 14 && ch.unicode() <= 38)
- goto state_39;
+ goto state_38;
if (ch.unicode() == 39)
- goto state_40;
- if (ch.unicode() >= 40 && ch.unicode() <= 91)
goto state_39;
+ if (ch.unicode() >= 40 && ch.unicode() <= 91)
+ goto state_38;
if (ch.unicode() == 92)
- goto state_41;
+ goto state_40;
if (ch.unicode() >= 93 && ch.unicode() <= 96)
- goto state_39;
+ goto state_38;
if ((ch.unicode() >= 'a' && ch.unicode() <= 'z') || (ch.unicode() >= 'A' && ch.unicode() <= 'Z') || ch.unicode() >= 256)
- goto state_39;
+ goto state_38;
if (ch.unicode() >= 123)
- goto state_39;
+ goto state_38;
goto out;
state_73:
lastAcceptingPos = pos;
token = QCss::INVALID;
ch = next();
if (ch.unicode() >= 1 && ch.unicode() <= 9)
- goto state_39;
- if (ch.unicode() == 10)
- goto state_86;
+ goto state_38;
if (ch.unicode() == 11)
- goto state_39;
+ goto state_38;
if (ch.unicode() >= 14 && ch.unicode() <= 38)
- goto state_39;
+ goto state_38;
if (ch.unicode() == 39)
- goto state_40;
- if (ch.unicode() >= 40 && ch.unicode() <= 91)
goto state_39;
+ if (ch.unicode() >= 40 && ch.unicode() <= 91)
+ goto state_38;
if (ch.unicode() == 92)
- goto state_41;
+ goto state_40;
if (ch.unicode() >= 93 && ch.unicode() <= 96)
- goto state_39;
+ goto state_38;
if ((ch.unicode() >= 'a' && ch.unicode() <= 'z') || (ch.unicode() >= 'A' && ch.unicode() <= 'Z') || ch.unicode() >= 256)
- goto state_39;
+ goto state_38;
if (ch.unicode() >= 123)
- goto state_39;
+ goto state_38;
goto out;
- state_75:
+ state_74:
lastAcceptingPos = pos;
token = QCss::NUMBER;
ch = next();
if (ch.unicode() == 37)
goto state_46;
if (ch.unicode() == 45)
- goto state_47;
+ goto state_48;
if (ch.unicode() >= 48 && ch.unicode() <= 57)
- goto state_75;
+ goto state_74;
if (ch.unicode() == 92)
- goto state_50;
- if (ch.unicode() == 95)
goto state_51;
+ if (ch.unicode() == 95)
+ goto state_50;
if ((ch.unicode() >= 'a' && ch.unicode() <= 'z') || (ch.unicode() >= 'A' && ch.unicode() <= 'Z') || ch.unicode() >= 256)
- goto state_51;
+ goto state_50;
goto out;
state_76:
lastAcceptingPos = pos;
token = QCss::LENGTH;
ch = next();
if (ch.unicode() == 45)
- goto state_77;
+ goto state_76;
if (ch.unicode() >= 48 && ch.unicode() <= 57)
- goto state_77;
+ goto state_76;
if (ch.unicode() == 92)
- goto state_78;
- if (ch.unicode() == 95)
- goto state_77;
- if ((ch.unicode() >= 'a' && ch.unicode() <= 'z') || (ch.unicode() >= 'A' && ch.unicode() <= 'Z') || ch.unicode() >= 256)
- goto state_77;
- goto out;
- state_77:
- lastAcceptingPos = pos;
- token = QCss::LENGTH;
- ch = next();
- if (ch.unicode() == 45)
goto state_77;
- if (ch.unicode() >= 48 && ch.unicode() <= 57)
- goto state_77;
- if (ch.unicode() == 92)
- goto state_78;
if (ch.unicode() == 95)
- goto state_77;
+ goto state_76;
if ((ch.unicode() >= 'a' && ch.unicode() <= 'z') || (ch.unicode() >= 'A' && ch.unicode() <= 'Z') || ch.unicode() >= 256)
- goto state_77;
+ goto state_76;
goto out;
- state_78:
+ state_77:
ch = next();
if (ch.unicode() >= 1 && ch.unicode() <= 9)
goto state_87;
@@ -1008,6 +993,21 @@ int QCssScanner_Generated::lex()
if (ch.unicode() >= 103)
goto state_87;
goto out;
+ state_78:
+ lastAcceptingPos = pos;
+ token = QCss::LENGTH;
+ ch = next();
+ if (ch.unicode() == 45)
+ goto state_76;
+ if (ch.unicode() >= 48 && ch.unicode() <= 57)
+ goto state_76;
+ if (ch.unicode() == 92)
+ goto state_77;
+ if (ch.unicode() == 95)
+ goto state_76;
+ if ((ch.unicode() >= 'a' && ch.unicode() <= 'z') || (ch.unicode() >= 'A' && ch.unicode() <= 'Z') || ch.unicode() >= 256)
+ goto state_76;
+ goto out;
state_79:
ch = next();
if (ch.unicode() == 45) {
@@ -1017,18 +1017,20 @@ int QCssScanner_Generated::lex()
goto out;
state_80:
lastAcceptingPos = pos;
- token = QCss::ATKEYWORD_SYM;
+ token = QCss::IDENT;
ch = next();
+ if (ch.unicode() == 40)
+ goto state_53;
if (ch.unicode() == 45)
- goto state_81;
+ goto state_54;
if (ch.unicode() >= 48 && ch.unicode() <= 57)
- goto state_81;
+ goto state_54;
if (ch.unicode() == 92)
- goto state_82;
+ goto state_55;
if (ch.unicode() == 95)
- goto state_81;
+ goto state_54;
if ((ch.unicode() >= 'a' && ch.unicode() <= 'z') || (ch.unicode() >= 'A' && ch.unicode() <= 'Z') || ch.unicode() >= 256)
- goto state_81;
+ goto state_54;
goto out;
state_81:
lastAcceptingPos = pos;
@@ -1060,23 +1062,36 @@ int QCssScanner_Generated::lex()
goto out;
state_83:
lastAcceptingPos = pos;
- token = QCss::IDENT;
+ token = QCss::ATKEYWORD_SYM;
ch = next();
- if (ch.unicode() == 40)
- goto state_58;
if (ch.unicode() == 45)
- goto state_59;
+ goto state_81;
if (ch.unicode() >= 48 && ch.unicode() <= 57)
- goto state_59;
+ goto state_81;
if (ch.unicode() == 92)
- goto state_60;
+ goto state_82;
if (ch.unicode() == 95)
- goto state_59;
+ goto state_81;
if ((ch.unicode() >= 'a' && ch.unicode() <= 'z') || (ch.unicode() >= 'A' && ch.unicode() <= 'Z') || ch.unicode() >= 256)
- goto state_59;
+ goto state_81;
goto out;
state_84:
lastAcceptingPos = pos;
+ token = QCss::HASH;
+ ch = next();
+ if (ch.unicode() == 45)
+ goto state_63;
+ if (ch.unicode() >= 48 && ch.unicode() <= 57)
+ goto state_63;
+ if (ch.unicode() == 92)
+ goto state_64;
+ if (ch.unicode() == 95)
+ goto state_63;
+ if ((ch.unicode() >= 'a' && ch.unicode() <= 'z') || (ch.unicode() >= 'A' && ch.unicode() <= 'Z') || ch.unicode() >= 256)
+ goto state_63;
+ goto out;
+ state_85:
+ lastAcceptingPos = pos;
token = QCss::INVALID;
ch = next();
if (ch.unicode() >= 1 && ch.unicode() <= 9)
@@ -1098,58 +1113,43 @@ int QCssScanner_Generated::lex()
if (ch.unicode() >= 123)
goto state_33;
goto out;
- state_85:
- lastAcceptingPos = pos;
- token = QCss::HASH;
- ch = next();
- if (ch.unicode() == 45)
- goto state_67;
- if (ch.unicode() >= 48 && ch.unicode() <= 57)
- goto state_67;
- if (ch.unicode() == 92)
- goto state_68;
- if (ch.unicode() == 95)
- goto state_67;
- if ((ch.unicode() >= 'a' && ch.unicode() <= 'z') || (ch.unicode() >= 'A' && ch.unicode() <= 'Z') || ch.unicode() >= 256)
- goto state_67;
- goto out;
state_86:
lastAcceptingPos = pos;
token = QCss::INVALID;
ch = next();
if (ch.unicode() >= 1 && ch.unicode() <= 9)
- goto state_39;
+ goto state_38;
if (ch.unicode() == 11)
- goto state_39;
+ goto state_38;
if (ch.unicode() >= 14 && ch.unicode() <= 38)
- goto state_39;
+ goto state_38;
if (ch.unicode() == 39)
- goto state_40;
- if (ch.unicode() >= 40 && ch.unicode() <= 91)
goto state_39;
+ if (ch.unicode() >= 40 && ch.unicode() <= 91)
+ goto state_38;
if (ch.unicode() == 92)
- goto state_41;
+ goto state_40;
if (ch.unicode() >= 93 && ch.unicode() <= 96)
- goto state_39;
+ goto state_38;
if ((ch.unicode() >= 'a' && ch.unicode() <= 'z') || (ch.unicode() >= 'A' && ch.unicode() <= 'Z') || ch.unicode() >= 256)
- goto state_39;
+ goto state_38;
if (ch.unicode() >= 123)
- goto state_39;
+ goto state_38;
goto out;
state_87:
lastAcceptingPos = pos;
token = QCss::LENGTH;
ch = next();
if (ch.unicode() == 45)
- goto state_77;
+ goto state_76;
if (ch.unicode() >= 48 && ch.unicode() <= 57)
- goto state_77;
+ goto state_76;
if (ch.unicode() == 92)
- goto state_78;
- if (ch.unicode() == 95)
goto state_77;
+ if (ch.unicode() == 95)
+ goto state_76;
if ((ch.unicode() >= 'a' && ch.unicode() <= 'z') || (ch.unicode() >= 'A' && ch.unicode() <= 'Z') || ch.unicode() >= 256)
- goto state_77;
+ goto state_76;
goto out;
state_89:
lastAcceptingPos = pos;
@@ -1176,4 +1176,3 @@ int QCssScanner_Generated::lex()
}
return token;
}
-
diff --git a/src/gui/text/qdistancefield.cpp b/src/gui/text/qdistancefield.cpp
index e7ca00b3a9..82bb617733 100644
--- a/src/gui/text/qdistancefield.cpp
+++ b/src/gui/text/qdistancefield.cpp
@@ -3,7 +3,7 @@
** Copyright (C) 2016 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
-** This file is part of the QtDeclarative module of the Qt Toolkit.
+** This file is part of the QtGui module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** Commercial License Usage
diff --git a/src/gui/text/qdistancefield_p.h b/src/gui/text/qdistancefield_p.h
index 27ab84332c..1a1b6866a2 100644
--- a/src/gui/text/qdistancefield_p.h
+++ b/src/gui/text/qdistancefield_p.h
@@ -3,7 +3,7 @@
** Copyright (C) 2016 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
-** This file is part of the QtDeclarative module of the Qt Toolkit.
+** This file is part of the QtGui module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** Commercial License Usage
@@ -72,7 +72,7 @@ int Q_GUI_EXPORT QT_DISTANCEFIELD_HIGHGLYPHCOUNT();
class Q_GUI_EXPORT QDistanceFieldData : public QSharedData
{
public:
- QDistanceFieldData() : glyph(0), width(0), height(0), nbytes(0), data(0) {}
+ QDistanceFieldData() : glyph(0), width(0), height(0), nbytes(0), data(nullptr) {}
QDistanceFieldData(const QDistanceFieldData &other);
~QDistanceFieldData();
diff --git a/src/gui/text/qfont.cpp b/src/gui/text/qfont.cpp
index a23ef95fde..164a2f60ab 100644
--- a/src/gui/text/qfont.cpp
+++ b/src/gui/text/qfont.cpp
@@ -116,7 +116,17 @@ bool QFontDef::exactMatch(const QFontDef &other) const
if (stretch != 0 && other.stretch != 0 && stretch != other.stretch)
return false;
+ if (families.size() != other.families.size())
+ return false;
+
QString this_family, this_foundry, other_family, other_foundry;
+ for (int i = 0; i < families.size(); ++i) {
+ QFontDatabase::parseFontName(families.at(i), this_foundry, this_family);
+ QFontDatabase::parseFontName(other.families.at(i), other_foundry, other_family);
+ if (this_family != other_family || this_foundry != other_foundry)
+ return false;
+ }
+
QFontDatabase::parseFontName(family, this_foundry, this_family);
QFontDatabase::parseFontName(other.family, other_foundry, other_family);
@@ -261,6 +271,9 @@ void QFontPrivate::resolve(uint mask, const QFontPrivate *other)
if (! (mask & QFont::FamilyResolved))
request.family = other->request.family;
+ if (!(mask & QFont::FamiliesResolved))
+ request.families = other->request.families;
+
if (! (mask & QFont::StyleNameResolved))
request.styleName = other->request.styleName;
@@ -424,7 +437,8 @@ QFontEngineData::~QFontEngineData()
\target fontmatching
The font matching algorithm works as follows:
\list 1
- \li If the specified font family exists and can be used to represent
+ \li The specified font families (set by setFamilies()) are searched for.
+ \li If not found, then if set the specified font family exists and can be used to represent
the writing system in use, it will be selected.
\li If not, a replacement font that supports the writing system is
selected. The font matching algorithm will try to find the
@@ -506,6 +520,7 @@ QFontEngineData::~QFontEngineData()
individually and then considered resolved.
\value FamilyResolved
+ \value FamiliesResolved
\value SizeResolved
\value StyleHintResolved
\value StyleStrategyResolved
@@ -547,14 +562,25 @@ QFontEngineData::~QFontEngineData()
\since 5.2
*/
+#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
/*!
+ \obsolete
Constructs a font from \a font for use on the paint device \a pd.
*/
QFont::QFont(const QFont &font, QPaintDevice *pd)
+ : QFont(font, static_cast<const QPaintDevice*>(pd))
+{}
+#endif
+
+/*!
+ \since 5.13
+ Constructs a font from \a font for use on the paint device \a pd.
+*/
+QFont::QFont(const QFont &font, const QPaintDevice *pd)
: resolve_mask(font.resolve_mask)
{
- Q_ASSERT(pd != 0);
- int dpi = pd->logicalDpiY();
+ Q_ASSERT(pd);
+ const int dpi = pd->logicalDpiY();
const int screen = 0;
if (font.d->dpi != dpi || font.d->screen != screen ) {
d = new QFontPrivate(*font.d);
@@ -1261,7 +1287,7 @@ QFont::StyleStrategy QFont::styleStrategy() const
/*!
Returns the StyleHint.
- The style hint affects the \l{#fontmatching}{font matching algorithm}.
+ The style hint affects the \l{QFont#fontmatching}{font matching algorithm}.
See \l QFont::StyleHint for the list of available hints.
\sa setStyleHint(), QFont::StyleStrategy, QFontInfo::styleHint()
@@ -1691,6 +1717,7 @@ bool QFont::operator<(const QFont &f) const
if (r1.stretch != r2.stretch) return r1.stretch < r2.stretch;
if (r1.styleHint != r2.styleHint) return r1.styleHint < r2.styleHint;
if (r1.styleStrategy != r2.styleStrategy) return r1.styleStrategy < r2.styleStrategy;
+ if (r1.families != r2.families) return r1.families < r2.families;
if (r1.family != r2.family) return r1.family < r2.family;
if (f.d->capital != d->capital) return f.d->capital < d->capital;
@@ -2056,7 +2083,7 @@ QString QFont::toString() const
\relates QFont
\since 5.3
*/
-uint qHash(const QFont &font, uint seed) Q_DECL_NOTHROW
+uint qHash(const QFont &font, uint seed) noexcept
{
return qHash(QFontPrivate::get(font)->request, seed);
}
@@ -2153,7 +2180,7 @@ void QFont::cacheStatistics()
*/
QString QFont::lastResortFamily() const
{
- return QString::fromLatin1("helvetica");
+ return QStringLiteral("helvetica");
}
#endif
@@ -2188,10 +2215,55 @@ QString QFont::defaultFamily() const
*/
QString QFont::lastResortFont() const
{
+QT_WARNING_PUSH
+QT_WARNING_DISABLE_DEPRECATED
return lastResortFamily();
+QT_WARNING_POP
}
#endif
+/*!
+ \since 5.13
+
+ Returns the requested font family names, i.e. the names set in the last
+ setFamilies() call or via the constructor. Otherwise it returns an
+ empty list.
+
+ \sa setFamily(), setFamilies(), family(), substitutes(), substitute()
+*/
+
+QStringList QFont::families() const
+{
+ return d->request.families;
+}
+
+/*!
+ \since 5.13
+
+ Sets the list of family names for the font. The names are case
+ insensitive and may include a foundry name. The first family in
+ \a families will be set as the main family for the font.
+
+ Each family name entry in \a families may optionally also include a
+ foundry name, e.g. "Helvetica [Cronyx]". If the family is
+ available from more than one foundry and the foundry isn't
+ specified, an arbitrary foundry is chosen. If the family isn't
+ available a family will be set using the \l{QFont}{font matching}
+ algorithm.
+
+ \sa family(), families(), setFamily(), setStyleHint(), QFontInfo
+*/
+
+void QFont::setFamilies(const QStringList &families)
+{
+ if ((resolve_mask & QFont::FamiliesResolved) && d->request.families == families)
+ return;
+ detach();
+ d->request.families = families;
+ resolve_mask |= QFont::FamiliesResolved;
+}
+
+
/*****************************************************************************
QFont stream functions
*****************************************************************************/
@@ -2256,6 +2328,8 @@ QDataStream &operator<<(QDataStream &s, const QFont &font)
s << (quint8)font.d->request.hintingPreference;
if (s.version() >= QDataStream::Qt_5_6)
s << (quint8)font.d->capital;
+ if (s.version() >= QDataStream::Qt_5_13)
+ s << font.d->request.families;
return s;
}
@@ -2351,6 +2425,11 @@ QDataStream &operator>>(QDataStream &s, QFont &font)
s >> value;
font.d->capital = QFont::Capitalization(value);
}
+ if (s.version() >= QDataStream::Qt_5_13) {
+ QStringList value;
+ s >> value;
+ font.d->request.families = value;
+ }
return s;
}
@@ -2874,9 +2953,9 @@ void QFontCache::insertEngine(const Key &key, QFontEngine *engine, bool insertMu
data.timestamp = ++current_timestamp;
if (insertMulti)
- engineCache.insertMulti(key, data);
- else
engineCache.insert(key, data);
+ else
+ engineCache.replace(key, data);
// only increase the cost if this is the first time we insert the engine
if (++engineCacheCount[engine] == 1)
increaseCost(engine->cache_cost);
@@ -3085,7 +3164,104 @@ void QFontCache::decreaseCache()
#ifndef QT_NO_DEBUG_STREAM
QDebug operator<<(QDebug stream, const QFont &font)
{
- return stream << "QFont(" << font.toString() << ')';
+ QDebugStateSaver saver(stream);
+ stream.nospace().noquote();
+ stream << "QFont(";
+
+ if (stream.verbosity() == QDebug::DefaultVerbosity) {
+ stream << font.toString() << ")";
+ return stream;
+ }
+
+ QString fontDescription;
+ QDebug debug(&fontDescription);
+ debug.nospace();
+
+ QFontPrivate priv;
+ const QFont defaultFont(&priv);
+
+ for (int property = QFont::FamilyResolved; property < QFont::AllPropertiesResolved; property <<= 1) {
+ const bool resolved = (font.resolve_mask & property) != 0;
+ if (!resolved && stream.verbosity() == QDebug::MinimumVerbosity)
+ continue;
+
+ #define QFONT_DEBUG_SKIP_DEFAULT(prop) \
+ if ((font.prop() == defaultFont.prop()) && stream.verbosity() == 1) \
+ continue;
+
+ QDebugStateSaver saver(debug);
+
+ switch (property) {
+ case QFont::FamilyResolved:
+ debug << font.family(); break;
+ case QFont::SizeResolved:
+ if (font.pointSizeF() >= 0)
+ debug << font.pointSizeF() << "pt";
+ else if (font.pixelSize() >= 0)
+ debug << font.pixelSize() << "px";
+ else
+ Q_UNREACHABLE();
+ break;
+ case QFont::StyleHintResolved:
+ QFONT_DEBUG_SKIP_DEFAULT(styleHint);
+ debug.verbosity(1) << font.styleHint(); break;
+ case QFont::StyleStrategyResolved:
+ QFONT_DEBUG_SKIP_DEFAULT(styleStrategy);
+ debug.verbosity(1) << font.styleStrategy(); break;
+ case QFont::WeightResolved:
+ debug.verbosity(1) << QFont::Weight(font.weight()); break;
+ case QFont::StyleResolved:
+ QFONT_DEBUG_SKIP_DEFAULT(style);
+ debug.verbosity(0) << font.style(); break;
+ case QFont::UnderlineResolved:
+ QFONT_DEBUG_SKIP_DEFAULT(underline);
+ debug << "underline=" << font.underline(); break;
+ case QFont::OverlineResolved:
+ QFONT_DEBUG_SKIP_DEFAULT(overline);
+ debug << "overline=" << font.overline(); break;
+ case QFont::StrikeOutResolved:
+ QFONT_DEBUG_SKIP_DEFAULT(strikeOut);
+ debug << "strikeOut=" << font.strikeOut(); break;
+ case QFont::FixedPitchResolved:
+ QFONT_DEBUG_SKIP_DEFAULT(fixedPitch);
+ debug << "fixedPitch=" << font.fixedPitch(); break;
+ case QFont::StretchResolved:
+ QFONT_DEBUG_SKIP_DEFAULT(stretch);
+ debug.verbosity(0) << QFont::Stretch(font.stretch()); break;
+ case QFont::KerningResolved:
+ QFONT_DEBUG_SKIP_DEFAULT(kerning);
+ debug << "kerning=" << font.kerning(); break;
+ case QFont::CapitalizationResolved:
+ QFONT_DEBUG_SKIP_DEFAULT(capitalization);
+ debug.verbosity(0) << font.capitalization(); break;
+ case QFont::LetterSpacingResolved:
+ QFONT_DEBUG_SKIP_DEFAULT(letterSpacing);
+ debug << "letterSpacing=" << font.letterSpacing();
+ debug.verbosity(0) << " (" << font.letterSpacingType() << ")";
+ break;
+ case QFont::HintingPreferenceResolved:
+ QFONT_DEBUG_SKIP_DEFAULT(hintingPreference);
+ debug.verbosity(0) << font.hintingPreference(); break;
+ case QFont::StyleNameResolved:
+ QFONT_DEBUG_SKIP_DEFAULT(styleName);
+ debug << "styleName=" << font.styleName(); break;
+ default:
+ continue;
+ };
+
+ #undef QFONT_DEBUG_SKIP_DEFAULT
+
+ debug << ", ";
+ }
+
+ if (stream.verbosity() > QDebug::MinimumVerbosity)
+ debug.verbosity(0) << "resolveMask=" << QFlags<QFont::ResolveProperties>(font.resolve_mask);
+ else
+ fontDescription.chop(2); // Last ', '
+
+ stream << fontDescription << ')';
+
+ return stream;
}
#endif
diff --git a/src/gui/text/qfont.h b/src/gui/text/qfont.h
index a94586166e..16685ed9e8 100644
--- a/src/gui/text/qfont.h
+++ b/src/gui/text/qfont.h
@@ -147,6 +147,7 @@ public:
Q_ENUM(SpacingType)
enum ResolveProperties {
+ NoPropertiesResolved = 0x0000,
FamilyResolved = 0x0001,
SizeResolved = 0x0002,
StyleHintResolved = 0x0004,
@@ -164,13 +165,18 @@ public:
WordSpacingResolved = 0x4000,
HintingPreferenceResolved = 0x8000,
StyleNameResolved = 0x10000,
- AllPropertiesResolved = 0x1ffff
+ FamiliesResolved = 0x20000,
+ AllPropertiesResolved = 0x3ffff
};
+ Q_ENUM(ResolveProperties)
QFont();
QFont(const QString &family, int pointSize = -1, int weight = -1, bool italic = false);
- QFont(const QFont &, QPaintDevice *pd);
- QFont(const QFont &);
+#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
+ QFont(const QFont &font, QPaintDevice *pd);
+#endif
+ QFont(const QFont &font, const QPaintDevice *pd);
+ QFont(const QFont &font);
~QFont();
void swap(QFont &other)
@@ -179,6 +185,9 @@ public:
QString family() const;
void setFamily(const QString &);
+ QStringList families() const;
+ void setFamilies(const QStringList &);
+
QString styleName() const;
void setStyleName(const QString &);
@@ -253,7 +262,7 @@ public:
operator QVariant() const;
bool isCopyOf(const QFont &) const;
#ifdef Q_COMPILER_RVALUE_REFS
- inline QFont &operator=(QFont &&other) Q_DECL_NOEXCEPT
+ inline QFont &operator=(QFont &&other) noexcept
{ qSwap(d, other.d); qSwap(resolve_mask, other.resolve_mask); return *this; }
#endif
@@ -328,13 +337,17 @@ private:
friend Q_GUI_EXPORT QDataStream &operator>>(QDataStream &, QFont &);
#endif
+#ifndef QT_NO_DEBUG_STREAM
+ friend Q_GUI_EXPORT QDebug operator<<(QDebug, const QFont &);
+#endif
+
QExplicitlySharedDataPointer<QFontPrivate> d;
uint resolve_mask;
};
Q_DECLARE_SHARED(QFont)
-Q_GUI_EXPORT uint qHash(const QFont &font, uint seed = 0) Q_DECL_NOTHROW;
+Q_GUI_EXPORT uint qHash(const QFont &font, uint seed = 0) noexcept;
inline bool QFont::bold() const
{ return weight() > Medium; }
diff --git a/src/gui/text/qfont_p.h b/src/gui/text/qfont_p.h
index 350ba7ce3c..db74ab0b65 100644
--- a/src/gui/text/qfont_p.h
+++ b/src/gui/text/qfont_p.h
@@ -78,6 +78,7 @@ struct QFontDef
}
QString family;
+ QStringList families;
QString styleName;
QStringList fallBackFamilies;
@@ -109,6 +110,7 @@ struct QFontDef
&& styleStrategy == other.styleStrategy
&& ignorePitch == other.ignorePitch && fixedPitch == other.fixedPitch
&& family == other.family
+ && families == other.families
&& styleName == other.styleName
&& hintingPreference == other.hintingPreference
;
@@ -122,6 +124,7 @@ struct QFontDef
if (styleHint != other.styleHint) return styleHint < other.styleHint;
if (styleStrategy != other.styleStrategy) return styleStrategy < other.styleStrategy;
if (family != other.family) return family < other.family;
+ if (families != other.families) return families < other.families;
if (styleName != other.styleName)
return styleName < other.styleName;
if (hintingPreference != other.hintingPreference) return hintingPreference < other.hintingPreference;
@@ -133,7 +136,7 @@ struct QFontDef
}
};
-inline uint qHash(const QFontDef &fd, uint seed = 0) Q_DECL_NOTHROW
+inline uint qHash(const QFontDef &fd, uint seed = 0) noexcept
{
return qHash(qRound64(fd.pixelSize*10000)) // use only 4 fractional digits
^ qHash(fd.weight)
@@ -144,6 +147,7 @@ inline uint qHash(const QFontDef &fd, uint seed = 0) Q_DECL_NOTHROW
^ qHash(fd.ignorePitch)
^ qHash(fd.fixedPitch)
^ qHash(fd.family, seed)
+ ^ qHash(fd.families, seed)
^ qHash(fd.styleName)
^ qHash(fd.hintingPreference)
;
@@ -161,7 +165,7 @@ public:
QFontEngine *engines[QChar::ScriptCount];
private:
- Q_DISABLE_COPY(QFontEngineData)
+ Q_DISABLE_COPY_MOVE(QFontEngineData)
};
@@ -210,7 +214,7 @@ private:
};
-class Q_AUTOTEST_EXPORT QFontCache : public QObject
+class Q_GUI_EXPORT QFontCache : public QObject
{
public:
// note: these static functions work on a per-thread basis
@@ -262,7 +266,7 @@ public:
// QFontEngine cache
struct Engine {
- Engine() : data(0), timestamp(0), hits(0) { }
+ Engine() : data(nullptr), timestamp(0), hits(0) { }
Engine(QFontEngine *d) : data(d), timestamp(0), hits(0) { }
QFontEngine *data;
@@ -270,7 +274,7 @@ public:
uint hits;
};
- typedef QMap<Key,Engine> EngineCache;
+ typedef QMultiMap<Key,Engine> EngineCache;
EngineCache engineCache;
QHash<QFontEngine *, int> engineCacheCount;
diff --git a/src/gui/text/qfontdatabase.cpp b/src/gui/text/qfontdatabase.cpp
index 196eebb353..82e40510ae 100644
--- a/src/gui/text/qfontdatabase.cpp
+++ b/src/gui/text/qfontdatabase.cpp
@@ -434,7 +434,7 @@ struct FallbacksCacheKey {
QChar::Script script;
};
-inline bool operator==(const FallbacksCacheKey &lhs, const FallbacksCacheKey &rhs) Q_DECL_NOTHROW
+inline bool operator==(const FallbacksCacheKey &lhs, const FallbacksCacheKey &rhs) noexcept
{
return lhs.script == rhs.script &&
lhs.styleHint == rhs.styleHint &&
@@ -442,12 +442,12 @@ inline bool operator==(const FallbacksCacheKey &lhs, const FallbacksCacheKey &rh
lhs.family == rhs.family;
}
-inline bool operator!=(const FallbacksCacheKey &lhs, const FallbacksCacheKey &rhs) Q_DECL_NOTHROW
+inline bool operator!=(const FallbacksCacheKey &lhs, const FallbacksCacheKey &rhs) noexcept
{
return !operator==(lhs, rhs);
}
-inline uint qHash(const FallbacksCacheKey &key, uint seed = 0) Q_DECL_NOTHROW
+inline uint qHash(const FallbacksCacheKey &key, uint seed = 0) noexcept
{
QtPrivate::QHashCombine hash;
seed = hash(seed, key.family);
@@ -696,20 +696,20 @@ static QStringList familyList(const QFontDef &req)
{
// list of families to try
QStringList family_list;
- if (req.family.isEmpty())
- return family_list;
- const auto list = req.family.splitRef(QLatin1Char(','));
- const int numFamilies = list.size();
- family_list.reserve(numFamilies);
- for (int i = 0; i < numFamilies; ++i) {
- QStringRef str = list.at(i).trimmed();
- if ((str.startsWith(QLatin1Char('"')) && str.endsWith(QLatin1Char('"')))
- || (str.startsWith(QLatin1Char('\'')) && str.endsWith(QLatin1Char('\''))))
- str = str.mid(1, str.length() - 2);
- family_list << str.toString();
+ family_list << req.families;
+ if (!req.family.isEmpty()) {
+ const auto list = req.family.splitRef(QLatin1Char(','));
+ const int numFamilies = list.size();
+ family_list.reserve(numFamilies);
+ for (int i = 0; i < numFamilies; ++i) {
+ QStringRef str = list.at(i).trimmed();
+ if ((str.startsWith(QLatin1Char('"')) && str.endsWith(QLatin1Char('"')))
+ || (str.startsWith(QLatin1Char('\'')) && str.endsWith(QLatin1Char('\''))))
+ str = str.mid(1, str.length() - 2);
+ family_list << str.toString();
+ }
}
-
// append the substitute list for each family in family_list
for (int i = 0, size = family_list.size(); i < size; ++i)
family_list += QFont::substitutes(family_list.at(i));
@@ -2688,9 +2688,8 @@ QFontEngine *QFontDatabase::findFont(const QFontDef &request, int script)
}
QString family_name, foundry_name;
-
- parseFontName(request.family, foundry_name, family_name);
-
+ const QString requestFamily = request.families.size() > 0 ? request.families.at(0) : request.family;
+ parseFontName(requestFamily, foundry_name, family_name);
QtFontDesc desc;
QList<int> blackListed;
int index = match(multi ? QChar::Script_Common : script, request, family_name, foundry_name, &desc, blackListed);
@@ -2703,8 +2702,8 @@ QFontEngine *QFontDatabase::findFont(const QFontDef &request, int script)
// Don't pass empty family names to the platform font database, since it will then invoke its own matching
// and we will be out of sync with the matched font.
- if (fontDef.family.isEmpty())
- fontDef.family = desc.family->name;
+ if (fontDef.families.isEmpty() && fontDef.family.isEmpty())
+ fontDef.families = QStringList(desc.family->name);
engine = loadEngine(script, fontDef, desc.family, desc.foundry, desc.style, desc.size);
@@ -2717,13 +2716,13 @@ QFontEngine *QFontDatabase::findFont(const QFontDef &request, int script)
}
if (!engine) {
- if (!request.family.isEmpty()) {
+ if (!requestFamily.isEmpty()) {
QFont::StyleHint styleHint = QFont::StyleHint(request.styleHint);
if (styleHint == QFont::AnyStyle && request.fixedPitch)
styleHint = QFont::TypeWriter;
QStringList fallbacks = request.fallBackFamilies
- + fallbacksForFamily(request.family,
+ + fallbacksForFamily(requestFamily,
QFont::Style(request.style),
styleHint,
QChar::Script(script));
@@ -2741,7 +2740,7 @@ QFontEngine *QFontDatabase::findFont(const QFontDef &request, int script)
index = match(multi ? QChar::Script_Common : script, def, def.family, QLatin1String(""), &desc, blackListed);
if (index >= 0) {
QFontDef loadDef = def;
- if (loadDef.family.isEmpty())
+ if (loadDef.families.isEmpty() && loadDef.family.isEmpty())
loadDef.family = desc.family->name;
engine = loadEngine(script, loadDef, desc.family, desc.foundry, desc.style, desc.size);
if (engine)
@@ -2782,7 +2781,10 @@ void QFontDatabase::load(const QFontPrivate *d, int script)
// look for the requested font in the engine data cache
// note: fallBackFamilies are not respected in the EngineData cache key;
// join them with the primary selection family to avoid cache misses
- req.family = fallBackFamilies.join(QLatin1Char(','));
+ if (!d->request.family.isEmpty())
+ req.family = fallBackFamilies.join(QLatin1Char(','));
+ if (!d->request.families.isEmpty())
+ req.families = fallBackFamilies;
d->engineData = fontCache->findEngineData(req);
if (!d->engineData) {
@@ -2803,14 +2805,14 @@ void QFontDatabase::load(const QFontPrivate *d, int script)
req.fallBackFamilies = fallBackFamilies;
if (!req.fallBackFamilies.isEmpty())
- req.family = req.fallBackFamilies.takeFirst();
+ req.families = QStringList(req.fallBackFamilies.takeFirst());
// list of families to try
QStringList family_list;
- if (!req.family.isEmpty()) {
+ if (!req.families.isEmpty()) {
// Add primary selection
- family_list << req.family;
+ family_list << req.families.at(0);
// add the default family
QString defaultFamily = QGuiApplication::font().family();
@@ -2824,11 +2826,11 @@ void QFontDatabase::load(const QFontPrivate *d, int script)
QStringList::ConstIterator it = family_list.constBegin(), end = family_list.constEnd();
for (; !fe && it != end; ++it) {
- req.family = *it;
+ req.families = QStringList(*it);
fe = QFontDatabase::findFont(req, script);
if (fe) {
- if (fe->type() == QFontEngine::Box && !req.family.isEmpty()) {
+ if (fe->type() == QFontEngine::Box && !req.families.at(0).isEmpty()) {
if (fe->ref.load() == 0)
delete fe;
fe = 0;
diff --git a/src/gui/text/qfontdatabase.h b/src/gui/text/qfontdatabase.h
index e6aef493bd..80b092f177 100644
--- a/src/gui/text/qfontdatabase.h
+++ b/src/gui/text/qfontdatabase.h
@@ -160,8 +160,8 @@ private:
static void createDatabase();
static void parseFontName(const QString &name, QString &foundry, QString &family);
static QString resolveFontFamilyAlias(const QString &family);
- static QFontEngine *findFont(const QFontDef &request, int script);
- static void load(const QFontPrivate *d, int script);
+ static QFontEngine *findFont(const QFontDef &request, int script /* QChar::Script */);
+ static void load(const QFontPrivate *d, int script /* QChar::Script */);
friend struct QFontDef;
friend class QFontPrivate;
diff --git a/src/gui/text/qfontengine.cpp b/src/gui/text/qfontengine.cpp
index 64623c86df..1719855e68 100644
--- a/src/gui/text/qfontengine.cpp
+++ b/src/gui/text/qfontengine.cpp
@@ -1022,8 +1022,8 @@ void QFontEngine::getUnscaledGlyph(glyph_t glyph, QPainterPath *path, glyph_metr
Returns \c true if the font table idetified by \a tag exists in the font;
returns \c false otherwise.
- If \a buffer is NULL, stores the size of the buffer required for the font table data,
- in bytes, in \a length. If \a buffer is not NULL and the capacity
+ If \a buffer is \nullptr, stores the size of the buffer required for the font table data,
+ in bytes, in \a length. If \a buffer is not \nullptr and the capacity
of the buffer, passed in \a length, is sufficient to store the font table data,
also copies the font table data to \a buffer.
@@ -1755,7 +1755,7 @@ QImage QFontEngineBox::alphaMapForGlyph(glyph_t)
// Multi engine
// ------------------------------------------------------------------
-static inline uchar highByte(glyph_t glyph)
+uchar QFontEngineMulti::highByte(glyph_t glyph)
{ return glyph >> 24; }
// strip high byte from glyph
@@ -1843,13 +1843,14 @@ QFontEngine *QFontEngineMulti::loadEngine(int at)
QFontDef request(fontDef);
request.styleStrategy |= QFont::NoFontMerging;
request.family = fallbackFamilyAt(at - 1);
+ request.families = QStringList(request.family);
// At this point, the main script of the text has already been considered
// when fetching the list of fallback families from the database, and the
// info about the actual script of the characters may have been discarded,
// so we do not check for writing system support, but instead just load
// the family indiscriminately.
- if (QFontEngine *engine = QFontDatabase::findFont(request, QFontDatabase::Any)) {
+ if (QFontEngine *engine = QFontDatabase::findFont(request, QChar::Script_Common)) {
engine->fontDef.weight = request.weight;
if (request.style > QFont::StyleNormal)
engine->fontDef.style = request.style;
diff --git a/src/gui/text/qfontengine_p.h b/src/gui/text/qfontengine_p.h
index a411e9ce4c..b922d50b4c 100644
--- a/src/gui/text/qfontengine_p.h
+++ b/src/gui/text/qfontengine_p.h
@@ -194,7 +194,7 @@ public:
virtual QImage *lockedAlphaMapForGlyph(glyph_t glyph, QFixed subPixelPosition,
GlyphFormat neededFormat,
const QTransform &t = QTransform(),
- QPoint *offset = 0);
+ QPoint *offset = nullptr);
virtual void unlockAlphaMapForGlyph();
virtual bool hasInternalCaching() const { return false; }
@@ -224,7 +224,7 @@ public:
virtual qreal minLeftBearing() const;
virtual qreal minRightBearing() const;
- virtual void getGlyphBearings(glyph_t glyph, qreal *leftBearing = 0, qreal *rightBearing = 0);
+ virtual void getGlyphBearings(glyph_t glyph, qreal *leftBearing = nullptr, qreal *rightBearing = nullptr);
inline bool canRender(uint ucs4) const { return glyphIndex(ucs4) != 0; }
virtual bool canRender(const QChar *str, int len) const;
@@ -234,7 +234,7 @@ public:
virtual int glyphCount() const;
virtual int glyphMargin(GlyphFormat format) { return format == Format_A32 ? 2 : 0; }
- virtual QFontEngine *cloneWithSize(qreal /*pixelSize*/) const { return 0; }
+ virtual QFontEngine *cloneWithSize(qreal /*pixelSize*/) const { return nullptr; }
virtual Qt::HANDLE handle() const;
@@ -292,33 +292,33 @@ public:
Holder() : ptr(nullptr), destroy_func(nullptr) {}
explicit Holder(void *p, qt_destroy_func_t d) : ptr(p), destroy_func(d) {}
~Holder() { if (ptr && destroy_func) destroy_func(ptr); }
- Holder(Holder &&other) Q_DECL_NOTHROW
+ Holder(Holder &&other) noexcept
: ptr(other.ptr),
destroy_func(other.destroy_func)
{
other.ptr = nullptr;
other.destroy_func = nullptr;
}
- Holder &operator=(Holder &&other) Q_DECL_NOTHROW
+ Holder &operator=(Holder &&other) noexcept
{ swap(other); return *this; }
- void swap(Holder &other) Q_DECL_NOTHROW
+ void swap(Holder &other) noexcept
{
qSwap(ptr, other.ptr);
qSwap(destroy_func, other.destroy_func);
}
- void *get() const Q_DECL_NOTHROW { return ptr; }
- void *release() Q_DECL_NOTHROW {
+ void *get() const noexcept { return ptr; }
+ void *release() noexcept {
void *result = ptr;
ptr = nullptr;
destroy_func = nullptr;
return result;
}
- void reset() Q_DECL_NOTHROW { Holder().swap(*this); }
- qt_destroy_func_t get_deleter() const Q_DECL_NOTHROW { return destroy_func; }
+ void reset() noexcept { Holder().swap(*this); }
+ qt_destroy_func_t get_deleter() const noexcept { return destroy_func; }
- bool operator!() const Q_DECL_NOTHROW { return !ptr; }
+ bool operator!() const noexcept { return !ptr; }
};
mutable Holder font_; // \ NOTE: Declared before m_glyphCaches, so font_, face_
@@ -390,7 +390,7 @@ inline bool operator ==(const QFontEngine::FaceId &f1, const QFontEngine::FaceId
}
inline uint qHash(const QFontEngine::FaceId &f, uint seed = 0)
- Q_DECL_NOEXCEPT_EXPR(noexcept(qHash(f.filename)))
+ noexcept(noexcept(qHash(f.filename)))
{
QtPrivate::QHashCombine hash;
seed = hash(seed, f.filename);
@@ -458,7 +458,7 @@ public:
virtual void recalcAdvances(QGlyphLayout *, ShaperFlags) const override;
virtual void doKerning(QGlyphLayout *, ShaperFlags) const override;
virtual void addOutlineToPath(qreal, qreal, const QGlyphLayout &, QPainterPath *, QTextItem::RenderFlags flags) override;
- virtual void getGlyphBearings(glyph_t glyph, qreal *leftBearing = 0, qreal *rightBearing = 0) override;
+ virtual void getGlyphBearings(glyph_t glyph, qreal *leftBearing = nullptr, qreal *rightBearing = nullptr) override;
virtual QFixed ascent() const override;
virtual QFixed capHeight() const override;
@@ -485,6 +485,8 @@ public:
void setFallbackFamiliesList(const QStringList &fallbackFamilies);
+ static uchar highByte(glyph_t glyph); // Used for determining engine
+
inline QFontEngine *engine(int at) const
{ Q_ASSERT(at < m_engines.size()); return m_engines.at(at); }
diff --git a/src/gui/text/qfontmetrics.cpp b/src/gui/text/qfontmetrics.cpp
index 407559ad51..c8dc8d676e 100644
--- a/src/gui/text/qfontmetrics.cpp
+++ b/src/gui/text/qfontmetrics.cpp
@@ -156,6 +156,8 @@ QFontMetrics::QFontMetrics(const QFont &font)
}
/*!
+ \since 5.13
+ \fn QFontMetrics::QFontMetrics(const QFont &font, const QPaintDevice *paintdevice)
Constructs a font metrics object for \a font and \a paintdevice.
The font metrics will be compatible with the paintdevice passed.
@@ -168,9 +170,21 @@ QFontMetrics::QFontMetrics(const QFont &font)
passed in the constructor at the time it is created, and is not
updated if the font's attributes are changed later.
*/
+
+#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
+/*!
+ \fn QFontMetrics::QFontMetrics(const QFont &font, QPaintDevice *paintdevice)
+ \obsolete
+ Identical to QFontMetrics::QFontMetrics(const QFont &font, const QPaintDevice *paintdevice)
+*/
+
+
QFontMetrics::QFontMetrics(const QFont &font, QPaintDevice *paintdevice)
+#else
+QFontMetrics::QFontMetrics(const QFont &font, const QPaintDevice *paintdevice)
+#endif
{
- int dpi = paintdevice ? paintdevice->logicalDpiY() : qt_defaultDpi();
+ const int dpi = paintdevice ? paintdevice->logicalDpiY() : qt_defaultDpi();
const int screen = 0;
if (font.d->dpi != dpi || font.d->screen != screen ) {
d = new QFontPrivate(*font.d);
@@ -1127,6 +1141,8 @@ QFontMetricsF::QFontMetricsF(const QFont &font)
}
/*!
+ \fn QFontMetricsF::QFontMetricsF(const QFont &font, const QPaintDevice *paintdevice)
+ \since 5.13
Constructs a font metrics object for \a font and \a paintdevice.
The font metrics will be compatible with the paintdevice passed.
@@ -1139,7 +1155,20 @@ QFontMetricsF::QFontMetricsF(const QFont &font)
passed in the constructor at the time it is created, and is not
updated if the font's attributes are changed later.
*/
+
+
+#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
+/*!
+ \fn QFontMetricsF::QFontMetricsF(const QFont &font, QPaintDevice *paintdevice)
+ \obsolete
+ Identical to QFontMetricsF::QFontMetricsF(const QFont &font, const QPaintDevice *paintdevice)
+*/
+
+
QFontMetricsF::QFontMetricsF(const QFont &font, QPaintDevice *paintdevice)
+#else
+QFontMetricsF::QFontMetricsF(const QFont &font, const QPaintDevice *paintdevice)
+#endif
{
int dpi = paintdevice ? paintdevice->logicalDpiY() : qt_defaultDpi();
const int screen = 0;
diff --git a/src/gui/text/qfontmetrics.h b/src/gui/text/qfontmetrics.h
index b6167a1d47..761cadde47 100644
--- a/src/gui/text/qfontmetrics.h
+++ b/src/gui/text/qfontmetrics.h
@@ -59,17 +59,29 @@ class Q_GUI_EXPORT QFontMetrics
{
public:
explicit QFontMetrics(const QFont &);
- QFontMetrics(const QFont &, QPaintDevice *pd);
+#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
+ QFontMetrics(const QFont &font, QPaintDevice *pd);
+#ifndef Q_QDOC
+ // the template is necessary to make QFontMetrics(font,nullptr) and QFontMetrics(font,NULL)
+ // not ambiguous. Implementation detail that should not be documented.
+ template<char = 0>
+#endif
+ QFontMetrics(const QFont &font, const QPaintDevice *pd)
+ : QFontMetrics(font, const_cast<QPaintDevice*>(pd))
+ {}
+#else
+ QFontMetrics(const QFont &font, const QPaintDevice *pd);
+#endif
QFontMetrics(const QFontMetrics &);
~QFontMetrics();
QFontMetrics &operator=(const QFontMetrics &);
#ifdef Q_COMPILER_RVALUE_REFS
- inline QFontMetrics &operator=(QFontMetrics &&other) Q_DECL_NOEXCEPT
+ inline QFontMetrics &operator=(QFontMetrics &&other) noexcept
{ qSwap(d, other.d); return *this; }
#endif
- void swap(QFontMetrics &other) Q_DECL_NOEXCEPT
+ void swap(QFontMetrics &other) noexcept
{ qSwap(d, other.d); }
int ascent() const;
@@ -92,8 +104,11 @@ public:
int rightBearing(QChar) const;
#if QT_DEPRECATED_SINCE(5, 11)
+ QT_DEPRECATED_X("Use QFontMetrics::horizontalAdvance")
int width(const QString &, int len = -1) const;
+ QT_DEPRECATED_X("Use QFontMetrics::horizontalAdvance")
int width(const QString &, int len, int flags) const;
+ QT_DEPRECATED_X("Use QFontMetrics::horizontalAdvance")
int width(QChar) const;
#endif
@@ -137,8 +152,20 @@ Q_DECLARE_SHARED(QFontMetrics)
class Q_GUI_EXPORT QFontMetricsF
{
public:
- explicit QFontMetricsF(const QFont &);
- QFontMetricsF(const QFont &, QPaintDevice *pd);
+ explicit QFontMetricsF(const QFont &font);
+#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
+ QFontMetricsF(const QFont &font, QPaintDevice *pd);
+#ifndef Q_QDOC
+ // the template is necessary to make QFontMetrics(font,nullptr) and QFontMetrics(font,NULL)
+ // not ambiguous. Implementation detail that should not be documented.
+ template<char = 0>
+#endif
+ QFontMetricsF(const QFont &font, const QPaintDevice *pd)
+ : QFontMetricsF(font, const_cast<QPaintDevice*>(pd))
+ {}
+#else
+ QFontMetricsF(const QFont &font, const QPaintDevice *pd);
+#endif
QFontMetricsF(const QFontMetrics &);
QFontMetricsF(const QFontMetricsF &);
~QFontMetricsF();
diff --git a/src/gui/text/qfragmentmap_p.h b/src/gui/text/qfragmentmap_p.h
index 35f60ac961..1d781352f8 100644
--- a/src/gui/text/qfragmentmap_p.h
+++ b/src/gui/text/qfragmentmap_p.h
@@ -216,7 +216,7 @@ private:
template <class Fragment>
QFragmentMapData<Fragment>::QFragmentMapData()
- : fragments(0)
+ : fragments(nullptr)
{
init();
}
diff --git a/src/gui/text/qglyphrun.h b/src/gui/text/qglyphrun.h
index 6182c4f749..9bb1d3c820 100644
--- a/src/gui/text/qglyphrun.h
+++ b/src/gui/text/qglyphrun.h
@@ -67,12 +67,12 @@ public:
QGlyphRun();
QGlyphRun(const QGlyphRun &other);
#ifdef Q_COMPILER_RVALUE_REFS
- QGlyphRun &operator=(QGlyphRun &&other) Q_DECL_NOTHROW { swap(other); return *this; }
+ QGlyphRun &operator=(QGlyphRun &&other) noexcept { swap(other); return *this; }
#endif
QGlyphRun &operator=(const QGlyphRun &other);
~QGlyphRun();
- void swap(QGlyphRun &other) Q_DECL_NOTHROW { qSwap(d, other.d); }
+ void swap(QGlyphRun &other) noexcept { qSwap(d, other.d); }
QRawFont rawFont() const;
void setRawFont(const QRawFont &rawFont);
diff --git a/src/gui/text/qglyphrun_p.h b/src/gui/text/qglyphrun_p.h
index 5b6bdad648..465c3c7000 100644
--- a/src/gui/text/qglyphrun_p.h
+++ b/src/gui/text/qglyphrun_p.h
@@ -65,7 +65,7 @@ class QGlyphRunPrivate: public QSharedData
{
public:
QGlyphRunPrivate()
- : flags(0)
+ : flags(nullptr)
, glyphIndexData(glyphIndexes.constData())
, glyphIndexDataSize(0)
, glyphPositionData(glyphPositions.constData())
diff --git a/src/gui/text/qharfbuzzng.cpp b/src/gui/text/qharfbuzzng.cpp
index 36bd81c76b..2f25aea92b 100644
--- a/src/gui/text/qharfbuzzng.cpp
+++ b/src/gui/text/qharfbuzzng.cpp
@@ -686,13 +686,11 @@ _hb_qt_font_create(QFontEngine *fe)
const int x_ppem = (fe->fontDef.pixelSize * fe->fontDef.stretch) / 100;
hb_font_set_funcs(font, hb_qt_get_font_funcs(), (void *)fe, NULL);
-#ifdef Q_OS_MAC
- hb_font_set_scale(font, QFixed(x_ppem).value(), QFixed(y_ppem).value());
-#else
hb_font_set_scale(font, QFixed(x_ppem).value(), -QFixed(y_ppem).value());
-#endif
hb_font_set_ppem(font, x_ppem, y_ppem);
+ hb_font_set_ptem(font, fe->fontDef.pointSize);
+
return font;
}
diff --git a/src/gui/text/qrawfont.cpp b/src/gui/text/qrawfont.cpp
index b2d8bf01af..a060448924 100644
--- a/src/gui/text/qrawfont.cpp
+++ b/src/gui/text/qrawfont.cpp
@@ -322,7 +322,7 @@ bool QRawFont::operator==(const QRawFont &other) const
\relates QRawFont
\since 5.8
*/
-uint qHash(const QRawFont &font, uint seed) Q_DECL_NOTHROW
+uint qHash(const QRawFont &font, uint seed) noexcept
{
return qHash(QRawFontPrivate::get(font)->fontEngine, seed);
}
diff --git a/src/gui/text/qrawfont.h b/src/gui/text/qrawfont.h
index 470f2694e4..3b84f642d3 100644
--- a/src/gui/text/qrawfont.h
+++ b/src/gui/text/qrawfont.h
@@ -80,12 +80,12 @@ public:
QFont::HintingPreference hintingPreference = QFont::PreferDefaultHinting);
QRawFont(const QRawFont &other);
#ifdef Q_COMPILER_RVALUE_REFS
- QRawFont &operator=(QRawFont &&other) Q_DECL_NOTHROW { swap(other); return *this; }
+ QRawFont &operator=(QRawFont &&other) noexcept { swap(other); return *this; }
#endif
QRawFont &operator=(const QRawFont &other);
~QRawFont();
- void swap(QRawFont &other) Q_DECL_NOTHROW { qSwap(d, other.d); }
+ void swap(QRawFont &other) noexcept { qSwap(d, other.d); }
bool isValid() const;
@@ -158,7 +158,7 @@ Q_DECLARE_SHARED(QRawFont)
Q_DECLARE_OPERATORS_FOR_FLAGS(QRawFont::LayoutFlags)
-Q_GUI_EXPORT uint qHash(const QRawFont &font, uint seed = 0) Q_DECL_NOTHROW;
+Q_GUI_EXPORT uint qHash(const QRawFont &font, uint seed = 0) noexcept;
inline QVector<QPointF> QRawFont::advancesForGlyphIndexes(const QVector<quint32> &glyphIndexes, QRawFont::LayoutFlags layoutFlags) const
{
diff --git a/src/gui/text/qrawfont_p.h b/src/gui/text/qrawfont_p.h
index 0fc8739bfb..dced165475 100644
--- a/src/gui/text/qrawfont_p.h
+++ b/src/gui/text/qrawfont_p.h
@@ -67,9 +67,9 @@ class Q_GUI_EXPORT QRawFontPrivate
{
public:
QRawFontPrivate()
- : fontEngine(0)
+ : fontEngine(nullptr)
, hintingPreference(QFont::PreferDefaultHinting)
- , thread(0)
+ , thread(nullptr)
{}
QRawFontPrivate(const QRawFontPrivate &other)
@@ -78,9 +78,9 @@ public:
, thread(other.thread)
{
#ifndef QT_NO_DEBUG
- Q_ASSERT(fontEngine == 0 || thread == QThread::currentThread());
+ Q_ASSERT(fontEngine == nullptr || thread == QThread::currentThread());
#endif
- if (fontEngine != 0)
+ if (fontEngine != nullptr)
fontEngine->ref.ref();
}
@@ -94,37 +94,37 @@ public:
inline void cleanUp()
{
- setFontEngine(0);
+ setFontEngine(nullptr);
hintingPreference = QFont::PreferDefaultHinting;
}
inline bool isValid() const
{
#ifndef QT_NO_DEBUG
- Q_ASSERT(fontEngine == 0 || thread == QThread::currentThread());
+ Q_ASSERT(fontEngine == nullptr || thread == QThread::currentThread());
#endif
- return fontEngine != 0;
+ return fontEngine != nullptr;
}
inline void setFontEngine(QFontEngine *engine)
{
#ifndef QT_NO_DEBUG
- Q_ASSERT(fontEngine == 0 || thread == QThread::currentThread());
+ Q_ASSERT(fontEngine == nullptr || thread == QThread::currentThread());
#endif
if (fontEngine == engine)
return;
- if (fontEngine != 0) {
+ if (fontEngine != nullptr) {
if (!fontEngine->ref.deref())
delete fontEngine;
#ifndef QT_NO_DEBUG
- thread = 0;
+ thread = nullptr;
#endif
}
fontEngine = engine;
- if (fontEngine != 0) {
+ if (fontEngine != nullptr) {
fontEngine->ref.ref();
#ifndef QT_NO_DEBUG
thread = QThread::currentThread();
diff --git a/src/gui/text/qstatictext.cpp b/src/gui/text/qstatictext.cpp
index 0026e3edfb..dd894f4d32 100644
--- a/src/gui/text/qstatictext.cpp
+++ b/src/gui/text/qstatictext.cpp
@@ -3,7 +3,7 @@
** Copyright (C) 2016 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
-** This file is part of the test suite of the Qt Toolkit.
+** This file is part of the QtGui module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** Commercial License Usage
diff --git a/src/gui/text/qstatictext.h b/src/gui/text/qstatictext.h
index e6a196d865..c6a0d158c1 100644
--- a/src/gui/text/qstatictext.h
+++ b/src/gui/text/qstatictext.h
@@ -3,7 +3,7 @@
** Copyright (C) 2016 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
-** This file is part of the test suite of the Qt Toolkit.
+** This file is part of the QtGui module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** Commercial License Usage
@@ -65,12 +65,12 @@ public:
explicit QStaticText(const QString &text);
QStaticText(const QStaticText &other);
#ifdef Q_COMPILER_RVALUE_REFS
- QStaticText &operator=(QStaticText &&other) Q_DECL_NOTHROW { swap(other); return *this; }
+ QStaticText &operator=(QStaticText &&other) noexcept { swap(other); return *this; }
#endif
QStaticText &operator=(const QStaticText &);
~QStaticText();
- void swap(QStaticText &other) Q_DECL_NOTHROW { qSwap(data, other.data); }
+ void swap(QStaticText &other) noexcept { qSwap(data, other.data); }
void setText(const QString &text);
QString text() const;
diff --git a/src/gui/text/qstatictext_p.h b/src/gui/text/qstatictext_p.h
index c4023488ff..8d6792216d 100644
--- a/src/gui/text/qstatictext_p.h
+++ b/src/gui/text/qstatictext_p.h
@@ -3,7 +3,7 @@
** Copyright (C) 2016 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
-** This file is part of the test suite of the Qt Toolkit.
+** This file is part of the QtGui module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** Commercial License Usage
@@ -80,7 +80,7 @@ class Q_GUI_EXPORT QStaticTextItem
public:
QStaticTextItem() : useBackendOptimizations(false),
userDataNeedsUpdate(0), usesRawFont(0),
- m_fontEngine(0), m_userData(0) {}
+ m_fontEngine(nullptr), m_userData(nullptr) {}
void setUserData(QStaticTextUserData *newUserData)
{
diff --git a/src/gui/text/qsyntaxhighlighter.cpp b/src/gui/text/qsyntaxhighlighter.cpp
index fcda17605f..cf584f6980 100644
--- a/src/gui/text/qsyntaxhighlighter.cpp
+++ b/src/gui/text/qsyntaxhighlighter.cpp
@@ -45,6 +45,7 @@
#include <private/qtextdocument_p.h>
#include <qtextlayout.h>
#include <qpointer.h>
+#include <qscopedvaluerollback.h>
#include <qtextobject.h>
#include <qtextcursor.h>
#include <qdebug.h>
@@ -68,14 +69,14 @@ public:
void reformatBlocks(int from, int charsRemoved, int charsAdded);
void reformatBlock(const QTextBlock &block);
- inline void rehighlight(QTextCursor &cursor, QTextCursor::MoveOperation operation) {
- inReformatBlocks = true;
+ inline void rehighlight(QTextCursor &cursor, QTextCursor::MoveOperation operation)
+ {
+ QScopedValueRollback<bool> bg(inReformatBlocks, true);
cursor.beginEditBlock();
int from = cursor.position();
cursor.movePosition(operation);
reformatBlocks(from, 0, cursor.position() - from);
cursor.endEditBlock();
- inReformatBlocks = false;
}
inline void _q_delayedRehighlight() {
@@ -157,14 +158,12 @@ void QSyntaxHighlighterPrivate::applyFormatChanges()
void QSyntaxHighlighterPrivate::_q_reformatBlocks(int from, int charsRemoved, int charsAdded)
{
- if (!inReformatBlocks)
+ if (!inReformatBlocks && !rehighlightPending)
reformatBlocks(from, charsRemoved, charsAdded);
}
void QSyntaxHighlighterPrivate::reformatBlocks(int from, int charsRemoved, int charsAdded)
{
- rehighlightPending = false;
-
QTextBlock block = doc->findBlock(from);
if (!block.isValid())
return;
@@ -299,7 +298,7 @@ void QSyntaxHighlighterPrivate::reformatBlock(const QTextBlock &block)
QSyntaxHighlighter::QSyntaxHighlighter(QObject *parent)
: QObject(*new QSyntaxHighlighterPrivate, parent)
{
- if (parent->inherits("QTextEdit")) {
+ if (parent && parent->inherits("QTextEdit")) {
QTextDocument *doc = parent->property("document").value<QTextDocument *>();
if (doc)
setDocument(doc);
@@ -346,8 +345,10 @@ void QSyntaxHighlighter::setDocument(QTextDocument *doc)
if (d->doc) {
connect(d->doc, SIGNAL(contentsChange(int,int,int)),
this, SLOT(_q_reformatBlocks(int,int,int)));
- d->rehighlightPending = true;
- QTimer::singleShot(0, this, SLOT(_q_delayedRehighlight()));
+ if (!d->doc->isEmpty()) {
+ d->rehighlightPending = true;
+ QTimer::singleShot(0, this, SLOT(_q_delayedRehighlight()));
+ }
}
}
@@ -376,6 +377,7 @@ void QSyntaxHighlighter::rehighlight()
QTextCursor cursor(d->doc);
d->rehighlight(cursor, QTextCursor::End);
+ d->rehighlightPending = false; // user manually did a full rehighlight
}
/*!
diff --git a/src/gui/text/qtextcursor.cpp b/src/gui/text/qtextcursor.cpp
index af8fcf369c..c88497840f 100644
--- a/src/gui/text/qtextcursor.cpp
+++ b/src/gui/text/qtextcursor.cpp
@@ -1145,6 +1145,15 @@ bool QTextCursor::isNull() const
\a pos using a \c MoveMode specified by \a m. The cursor is positioned
between characters.
+ \note The "characters" in this case refer to the string of QChar
+ objects, i.e. 16-bit Unicode characters, and \a pos is considered
+ an index into this string. This does not necessarily correspond to
+ individual graphemes in the writing system, as a single grapheme may
+ be represented by multiple Unicode characters, such as in the case
+ of surrogate pairs, linguistic ligatures or diacritics. For a more
+ generic approach to navigating the document, use movePosition(),
+ which will respect the actual grapheme boundaries in the text.
+
\sa position(), movePosition(), anchor()
*/
void QTextCursor::setPosition(int pos, MoveMode m)
@@ -1176,6 +1185,13 @@ void QTextCursor::setPosition(int pos, MoveMode m)
Returns the absolute position of the cursor within the document.
The cursor is positioned between characters.
+ \note The "characters" in this case refer to the string of QChar
+ objects, i.e. 16-bit Unicode characters, and the position is considered
+ an index into this string. This does not necessarily correspond to
+ individual graphemes in the writing system, as a single grapheme may
+ be represented by multiple Unicode characters, such as in the case
+ of surrogate pairs, linguistic ligatures or diacritics.
+
\sa setPosition(), movePosition(), anchor(), positionInBlock()
*/
int QTextCursor::position() const
@@ -1192,6 +1208,13 @@ int QTextCursor::position() const
This is equivalent to \c{ position() - block().position()}.
+ \note The "characters" in this case refer to the string of QChar
+ objects, i.e. 16-bit Unicode characters, and the position is considered
+ an index into this string. This does not necessarily correspond to
+ individual graphemes in the writing system, as a single grapheme may
+ be represented by multiple Unicode characters, such as in the case
+ of surrogate pairs, linguistic ligatures or diacritics.
+
\sa position()
*/
int QTextCursor::positionInBlock() const
@@ -2116,7 +2139,7 @@ QTextList *QTextCursor::createList(QTextListFormat::Style style)
/*!
Returns the current list if the cursor position() is inside a
- block that is part of a list; otherwise returns 0.
+ block that is part of a list; otherwise returns \nullptr.
\sa insertList(), createList()
*/
@@ -2176,7 +2199,7 @@ QTextTable *QTextCursor::insertTable(int rows, int cols, const QTextTableFormat
/*!
Returns a pointer to the current table if the cursor position()
- is inside a block that is part of a table; otherwise returns 0.
+ is inside a block that is part of a table; otherwise returns \nullptr.
\sa insertTable()
*/
@@ -2213,7 +2236,7 @@ QTextFrame *QTextCursor::insertFrame(const QTextFrameFormat &format)
}
/*!
- Returns a pointer to the current frame. Returns 0 if the cursor is invalid.
+ Returns a pointer to the current frame. Returns \nullptr if the cursor is invalid.
\sa insertFrame()
*/
diff --git a/src/gui/text/qtextcursor.h b/src/gui/text/qtextcursor.h
index 1a00b753ad..4a9c614887 100644
--- a/src/gui/text/qtextcursor.h
+++ b/src/gui/text/qtextcursor.h
@@ -74,12 +74,12 @@ public:
explicit QTextCursor(const QTextBlock &block);
QTextCursor(const QTextCursor &cursor);
#ifdef Q_COMPILER_RVALUE_REFS
- QTextCursor &operator=(QTextCursor &&other) Q_DECL_NOTHROW { swap(other); return *this; }
+ QTextCursor &operator=(QTextCursor &&other) noexcept { swap(other); return *this; }
#endif
QTextCursor &operator=(const QTextCursor &other);
~QTextCursor();
- void swap(QTextCursor &other) Q_DECL_NOTHROW { qSwap(d, other.d); }
+ void swap(QTextCursor &other) noexcept { qSwap(d, other.d); }
bool isNull() const;
diff --git a/src/gui/text/qtextdocument.cpp b/src/gui/text/qtextdocument.cpp
index 5d88530e65..fd3473b32e 100644
--- a/src/gui/text/qtextdocument.cpp
+++ b/src/gui/text/qtextdocument.cpp
@@ -51,7 +51,9 @@
#include <qregularexpression.h>
#endif
#include <qvarlengtharray.h>
+#if QT_CONFIG(textcodec)
#include <qtextcodec.h>
+#endif
#include <qthread.h>
#include <qcoreapplication.h>
#include <qmetaobject.h>
@@ -153,7 +155,7 @@ bool Qt::mightBeRichText(const QString& text)
This function is defined in the \c <QTextDocument> header file.
- \sa escape(), mightBeRichText()
+ \sa QString::toHtmlEscaped(), mightBeRichText()
*/
QString Qt::convertFromPlainText(const QString &plain, Qt::WhiteSpaceMode mode)
{
@@ -209,7 +211,7 @@ QString Qt::convertFromPlainText(const QString &plain, Qt::WhiteSpaceMode mode)
This function is defined in the \c <QTextDocument> header file.
*/
-#ifndef QT_NO_TEXTCODEC
+#if QT_CONFIG(textcodec)
QTextCodec *Qt::codecForHtml(const QByteArray &ba)
{
return QTextCodec::codecForHtml(ba);
@@ -1910,7 +1912,7 @@ static void printPage(int index, QPainter *painter, const QTextDocument *doc, co
}
/*!
- Prints the document to the given \a printer. The QPageablePaintDevice must be
+ Prints the document to the given \a printer. The QPagedPaintDevice must be
set up before being used with this function.
This is only a convenience method to print the whole document to the printer.
@@ -2661,10 +2663,10 @@ void QTextHtmlExporter::emitFragment(const QTextFragment &fragment)
bool closeAnchor = false;
if (format.isAnchor()) {
- const QString name = format.anchorName();
- if (!name.isEmpty()) {
+ const auto names = format.anchorNames();
+ if (!names.isEmpty()) {
html += QLatin1String("<a name=\"");
- html += name.toHtmlEscaped();
+ html += names.constFirst().toHtmlEscaped();
html += QLatin1String("\"></a>");
}
const QString href = format.anchorHref();
diff --git a/src/gui/text/qtextdocument.h b/src/gui/text/qtextdocument.h
index 33c0b48683..c9b22e053b 100644
--- a/src/gui/text/qtextdocument.h
+++ b/src/gui/text/qtextdocument.h
@@ -75,7 +75,7 @@ namespace Qt
Q_GUI_EXPORT bool mightBeRichText(const QString&);
Q_GUI_EXPORT QString convertFromPlainText(const QString &plain, WhiteSpaceMode mode = WhiteSpacePre);
-#if !defined(QT_NO_TEXTCODEC) || defined(Q_CLANG_QDOC)
+#if QT_CONFIG(textcodec) || defined(Q_CLANG_QDOC)
Q_GUI_EXPORT QTextCodec *codecForHtml(const QByteArray &ba);
#endif
}
diff --git a/src/gui/text/qtextdocument_p.cpp b/src/gui/text/qtextdocument_p.cpp
index 66e038122c..0e3c8d0e83 100644
--- a/src/gui/text/qtextdocument_p.cpp
+++ b/src/gui/text/qtextdocument_p.cpp
@@ -40,6 +40,7 @@
#include <private/qtools_p.h>
#include <qdebug.h>
+#include <qscopedvaluerollback.h>
#include "qtextdocument_p.h"
#include "qtextdocument.h"
#include <qtextformat.h>
@@ -274,9 +275,10 @@ void QTextDocumentPrivate::clear()
rtFrame = 0;
init();
cursors = oldCursors;
- inContentsChange = true;
- q->contentsChange(0, len, 0);
- inContentsChange = false;
+ {
+ QScopedValueRollback<bool> bg(inContentsChange, true);
+ emit q->contentsChange(0, len, 0);
+ }
if (lout)
lout->documentChanged(0, len, 0);
} QT_CATCH(...) {
@@ -309,9 +311,10 @@ void QTextDocumentPrivate::setLayout(QAbstractTextDocumentLayout *layout)
it->free();
emit q->documentLayoutChanged();
- inContentsChange = true;
- emit q->contentsChange(0, 0, length());
- inContentsChange = false;
+ {
+ QScopedValueRollback<bool> bg(inContentsChange, true);
+ emit q->contentsChange(0, 0, length());
+ }
if (lout)
lout->documentChanged(0, 0, length());
}
@@ -1213,9 +1216,8 @@ void QTextDocumentPrivate::finishEdit()
if (lout && docChangeFrom >= 0) {
if (!inContentsChange) {
- inContentsChange = true;
+ QScopedValueRollback<bool> bg(inContentsChange, true);
emit q->contentsChange(docChangeFrom, docChangeOldLength, docChangeLength);
- inContentsChange = false;
}
lout->documentChanged(docChangeFrom, docChangeOldLength, docChangeLength);
}
diff --git a/src/gui/text/qtextdocument_p.h b/src/gui/text/qtextdocument_p.h
index cad9131fbf..a8e17bfc08 100644
--- a/src/gui/text/qtextdocument_p.h
+++ b/src/gui/text/qtextdocument_p.h
@@ -101,10 +101,10 @@ class QTextBlockData : public QFragment<3>
{
public:
inline void initialize()
- { layout = 0; userData = 0; userState = -1; revision = 0; hidden = 0; }
+ { layout = nullptr; userData = nullptr; userState = -1; revision = 0; hidden = 0; }
void invalidate() const;
inline void free()
- { delete layout; layout = 0; delete userData; userData = 0; }
+ { delete layout; layout = nullptr; delete userData; userData = nullptr; }
mutable int format;
// ##### probably store a QTextEngine * here!
@@ -339,6 +339,7 @@ private:
int lastBlockCount;
public:
+ bool inContentsChange;
QTextOption defaultTextOption;
Qt::CursorMoveStyle defaultCursorMoveStyle;
#ifndef QT_NO_CSSPARSER
@@ -346,7 +347,6 @@ public:
#endif
int maximumBlockCount;
uint needsEnsureMaximumBlockCount : 1;
- uint inContentsChange : 1;
uint blockCursorAdjustment : 1;
QSizeF pageSize;
QString title;
diff --git a/src/gui/text/qtextdocumentfragment.cpp b/src/gui/text/qtextdocumentfragment.cpp
index f0eff2d4f3..aef4ea1522 100644
--- a/src/gui/text/qtextdocumentfragment.cpp
+++ b/src/gui/text/qtextdocumentfragment.cpp
@@ -43,7 +43,6 @@
#include "qtextlist.h"
#include <qdebug.h>
-#include <qtextcodec.h>
#include <qbytearray.h>
#include <qdatastream.h>
#include <qdatetime.h>
@@ -543,8 +542,10 @@ void QTextHtmlImporter::import()
}
}
- if (currentNode->charFormat.isAnchor() && !currentNode->charFormat.anchorName().isEmpty()) {
- namedAnchors.append(currentNode->charFormat.anchorName());
+ if (currentNode->charFormat.isAnchor()) {
+ const auto names = currentNode->charFormat.anchorNames();
+ if (!names.isEmpty())
+ namedAnchors.append(names.constFirst());
}
if (appendNodeText())
@@ -1140,7 +1141,8 @@ QTextHtmlImporter::ProcessNodeResult QTextHtmlImporter::processBlockNode()
// ####################
// block.setFloatPosition(node->cssFloat);
- if (wsm == QTextHtmlParserNode::WhiteSpacePre) {
+ if (wsm == QTextHtmlParserNode::WhiteSpacePre
+ || wsm == QTextHtmlParserNode::WhiteSpaceNoWrap) {
block.setNonBreakableLines(true);
modifiedBlockFormat = true;
}
diff --git a/src/gui/text/qtextdocumentfragment_p.h b/src/gui/text/qtextdocumentfragment_p.h
index 02a6a429fa..67b0c2c600 100644
--- a/src/gui/text/qtextdocumentfragment_p.h
+++ b/src/gui/text/qtextdocumentfragment_p.h
@@ -109,7 +109,7 @@ public:
uint importedFromPlainText : 1;
private:
- Q_DISABLE_COPY(QTextDocumentFragmentPrivate)
+ Q_DISABLE_COPY_MOVE(QTextDocumentFragmentPrivate)
};
#ifndef QT_NO_TEXTHTMLPARSER
@@ -125,7 +125,7 @@ public:
QTextHtmlImporter(QTextDocument *_doc, const QString &html,
ImportMode mode,
- const QTextDocument *resourceProvider = 0);
+ const QTextDocument *resourceProvider = nullptr);
void import();
@@ -163,7 +163,7 @@ private:
#endif
struct TableCellIterator
{
- inline TableCellIterator(QTextTable *t = 0) : table(t), row(0), column(0) {}
+ inline TableCellIterator(QTextTable *t = nullptr) : table(t), row(0), column(0) {}
inline TableCellIterator &operator++() {
if (atEnd())
@@ -182,7 +182,7 @@ private:
return *this;
}
- inline bool atEnd() const { return table == 0 || row >= table->rows(); }
+ inline bool atEnd() const { return table == nullptr || row >= table->rows(); }
QTextTableCell cell() const { return table->cellAt(row, column); }
diff --git a/src/gui/text/qtextdocumentlayout.cpp b/src/gui/text/qtextdocumentlayout.cpp
index a9227f0171..2e1a2b5bff 100644
--- a/src/gui/text/qtextdocumentlayout.cpp
+++ b/src/gui/text/qtextdocumentlayout.cpp
@@ -58,23 +58,17 @@
#include <limits.h>
#include <qbasictimer.h>
#include "private/qfunctions_p.h"
+#include <qloggingcategory.h>
#include <algorithm>
-// #define LAYOUT_DEBUG
-
-#ifdef LAYOUT_DEBUG
-#define LDEBUG qDebug()
-#define INC_INDENT debug_indent += " "
-#define DEC_INDENT debug_indent = debug_indent.left(debug_indent.length()-2)
-#else
-#define LDEBUG if(0) qDebug()
-#define INC_INDENT do {} while(0)
-#define DEC_INDENT do {} while(0)
-#endif
-
QT_BEGIN_NAMESPACE
+Q_LOGGING_CATEGORY(lcDraw, "qt.text.drawing")
+Q_LOGGING_CATEGORY(lcHit, "qt.text.hittest")
+Q_LOGGING_CATEGORY(lcLayout, "qt.text.layout")
+Q_LOGGING_CATEGORY(lcTable, "qt.text.layout.table")
+
// ################ should probably add frameFormatChange notification!
struct QTextLayoutStruct;
@@ -155,7 +149,7 @@ struct QTextLayoutStruct {
{ return pageHeight == 0 ? 0 : (absoluteY() / pageHeight).truncate(); }
inline void newPage()
- { if (pageHeight == QFIXED_MAX) return; pageBottom += pageHeight; y = pageBottom - pageHeight + pageBottomMargin + pageTopMargin - frameY; }
+ { if (pageHeight == QFIXED_MAX) return; pageBottom += pageHeight; y = qMax(y, pageBottom - pageHeight + pageBottomMargin + pageTopMargin - frameY); }
};
class QTextTableData : public QTextFrameData
@@ -583,16 +577,16 @@ QTextDocumentLayoutPrivate::hitTest(QTextFrame *frame, const QFixedPoint &point,
QTextFrame *rootFrame = docPrivate->rootFrame();
-// LDEBUG << "checking frame" << frame->firstPosition() << "point=" << point
-// << "position" << fd->position << "size" << fd->size;
+ qCDebug(lcHit) << "checking frame" << frame->firstPosition() << "point=" << point.toPointF()
+ << "position" << fd->position.toPointF() << "size" << fd->size.toSizeF();
if (frame != rootFrame) {
if (relativePoint.y < 0 || relativePoint.x < 0) {
*position = frame->firstPosition() - 1;
-// LDEBUG << "before pos=" << *position;
+ qCDebug(lcHit) << "before pos=" << *position;
return PointBefore;
} else if (relativePoint.y > fd->size.height || relativePoint.x > fd->size.width) {
*position = frame->lastPosition() + 1;
-// LDEBUG << "after pos=" << *position;
+ qCDebug(lcHit) << "after pos=" << *position;
return PointAfter;
}
}
@@ -666,8 +660,6 @@ QTextDocumentLayoutPrivate::HitPoint
QTextDocumentLayoutPrivate::hitTest(QTextFrame::Iterator it, HitPoint hit, const QFixedPoint &p,
int *position, QTextLayout **l, Qt::HitTestAccuracy accuracy) const
{
- INC_INDENT;
-
for (; !it.atEnd(); ++it) {
QTextFrame *c = it.currentFrame();
HitPoint hp;
@@ -693,8 +685,7 @@ QTextDocumentLayoutPrivate::hitTest(QTextFrame::Iterator it, HitPoint hit, const
}
}
- DEC_INDENT;
-// LDEBUG << "inside=" << hit << " pos=" << *position;
+ qCDebug(lcHit) << "inside=" << hit << " pos=" << *position;
return hit;
}
@@ -741,15 +732,14 @@ QTextDocumentLayoutPrivate::hitTest(const QTextBlock &bl, const QFixedPoint &poi
QTextLayout *tl = bl.layout();
QRectF textrect = tl->boundingRect();
textrect.translate(tl->position());
-// LDEBUG << " checking block" << bl.position() << "point=" << point
-// << " tlrect" << textrect;
+ qCDebug(lcHit) << " checking block" << bl.position() << "point=" << point.toPointF() << " tlrect" << textrect;
*position = bl.position();
if (point.y.toReal() < textrect.top()) {
-// LDEBUG << " before pos=" << *position;
+ qCDebug(lcHit) << " before pos=" << *position;
return PointBefore;
} else if (point.y.toReal() > textrect.bottom()) {
*position += bl.length();
-// LDEBUG << " after pos=" << *position;
+ qCDebug(lcHit) << " after pos=" << *position;
return PointAfter;
}
@@ -781,7 +771,7 @@ QTextDocumentLayoutPrivate::hitTest(const QTextBlock &bl, const QFixedPoint &poi
}
*position += off;
-// LDEBUG << " inside=" << hit << " pos=" << *position;
+ qCDebug(lcHit) << " inside=" << hit << " pos=" << *position;
return hit;
}
@@ -944,8 +934,7 @@ void QTextDocumentLayoutPrivate::drawFrame(const QPointF &offset, QPainter *pain
|| off.x() > context.clip.right() || off.x() + fd->size.width.toReal() < context.clip.left()))
return;
-// LDEBUG << debug_indent << "drawFrame" << frame->firstPosition() << "--" << frame->lastPosition() << "at" << offset;
-// INC_INDENT;
+ qCDebug(lcDraw) << "drawFrame" << frame->firstPosition() << "--" << frame->lastPosition() << "at" << offset;
// if the cursor is /on/ a table border we may need to repaint it
// afterwards, as we usually draw the decoration first
@@ -1076,8 +1065,6 @@ void QTextDocumentLayoutPrivate::drawFrame(const QPointF &offset, QPainter *pain
painter->setPen(oldPen);
}
-// DEC_INDENT;
-
return;
}
@@ -1280,7 +1267,7 @@ void QTextDocumentLayoutPrivate::drawBlock(const QPointF &offset, QPainter *pain
r.translate(offset + tl->position());
if (!bl.isVisible() || (context.clip.isValid() && (r.bottom() < context.clip.y() || r.top() > context.clip.bottom())))
return;
-// LDEBUG << debug_indent << "drawBlock" << bl.position() << "at" << offset << "br" << tl->boundingRect();
+ qCDebug(lcDraw) << "drawBlock" << bl.position() << "at" << offset << "br" << tl->boundingRect();
QTextBlockFormat blockFormat = bl.blockFormat();
@@ -1512,7 +1499,7 @@ QTextLayoutStruct QTextDocumentLayoutPrivate::layoutCell(QTextTable *t, const QT
int layoutFrom, int layoutTo, QTextTableData *td,
QFixed absoluteTableY, bool withPageBreaks)
{
- LDEBUG << "layoutCell";
+ qCDebug(lcTable) << "layoutCell";
QTextLayoutStruct layoutStruct;
layoutStruct.frame = t;
layoutStruct.minimumWidth = 0;
@@ -1587,7 +1574,7 @@ QTextLayoutStruct QTextDocumentLayoutPrivate::layoutCell(QTextTable *t, const QT
QRectF QTextDocumentLayoutPrivate::layoutTable(QTextTable *table, int layoutFrom, int layoutTo, QFixed parentY)
{
- LDEBUG << "layoutTable";
+ qCDebug(lcTable) << "layoutTable from" << layoutFrom << "to" << layoutTo << "parentY" << parentY;
QTextTableData *td = static_cast<QTextTableData *>(data(table));
Q_ASSERT(td->sizeDirty);
const int rows = table->rows();
@@ -1709,6 +1696,7 @@ recalc_minmax_widths:
if (length.type() == QTextLength::FixedLength) {
td->minWidths[i] = td->widths[i] = qMax(scaleToDevice(QFixed::fromReal(length.rawValue())), td->minWidths.at(i));
remainingWidth -= td->widths.at(i);
+ qCDebug(lcTable) << "column" << i << "has width constraint" << td->minWidths.at(i) << "px, remaining width now" << remainingWidth;
} else if (length.type() == QTextLength::PercentageLength) {
totalPercentage += QFixed::fromReal(length.rawValue());
} else if (length.type() == QTextLength::VariableLength) {
@@ -1716,6 +1704,7 @@ recalc_minmax_widths:
td->widths[i] = td->minWidths.at(i);
remainingWidth -= td->minWidths.at(i);
+ qCDebug(lcTable) << "column" << i << "has variable width, min" << td->minWidths.at(i) << "remaining width now" << remainingWidth;
}
totalMinWidth += td->minWidths.at(i);
}
@@ -1735,6 +1724,8 @@ recalc_minmax_widths:
} else {
td->widths[i] = td->minWidths.at(i);
}
+ qCDebug(lcTable) << "column" << i << "has width constraint" << columnWidthConstraints.at(i).rawValue()
+ << "%, allocated width" << td->widths[i] << "remaining width now" << remainingWidth;
remainingWidth -= td->widths.at(i);
}
}
@@ -1978,9 +1969,12 @@ relayout:
td->minimumWidth += rightMargin - td->border;
td->maximumWidth = td->columnPositions.at(0);
- for (int i = 0; i < columns; ++i)
+ for (int i = 0; i < columns; ++i) {
if (td->maxWidths.at(i) != QFIXED_MAX)
td->maximumWidth += td->maxWidths.at(i) + 2 * td->border + cellSpacing;
+ qCDebug(lcTable) << "column" << i << "has final width" << td->widths.at(i).toReal()
+ << "min" << td->minWidths.at(i).toReal() << "max" << td->maxWidths.at(i).toReal();
+ }
td->maximumWidth += rightMargin - td->border;
td->updateTableSize();
@@ -2052,9 +2046,8 @@ void QTextDocumentLayoutPrivate::positionFloat(QTextFrame *frame, QTextLine *cur
QRectF QTextDocumentLayoutPrivate::layoutFrame(QTextFrame *f, int layoutFrom, int layoutTo, QFixed parentY)
{
- LDEBUG << "layoutFrame (pre)";
+ qCDebug(lcLayout, "layoutFrame (%d--%d), parent=%p", f->firstPosition(), f->lastPosition(), f->parentFrame());
Q_ASSERT(data(f)->sizeDirty);
-// qDebug("layouting frame (%d--%d), parent=%p", f->firstPosition(), f->lastPosition(), f->parentFrame());
QTextFrameFormat fformat = f->frameFormat();
@@ -2076,9 +2069,8 @@ QRectF QTextDocumentLayoutPrivate::layoutFrame(QTextFrame *f, int layoutFrom, in
QRectF QTextDocumentLayoutPrivate::layoutFrame(QTextFrame *f, int layoutFrom, int layoutTo, QFixed frameWidth, QFixed frameHeight, QFixed parentY)
{
- LDEBUG << "layoutFrame from=" << layoutFrom << "to=" << layoutTo;
+ qCDebug(lcLayout, "layoutFrame (%d--%d), parent=%p", f->firstPosition(), f->lastPosition(), f->parentFrame());
Q_ASSERT(data(f)->sizeDirty);
-// qDebug("layouting frame (%d--%d), parent=%p", f->firstPosition(), f->lastPosition(), f->parentFrame());
QTextFrameData *fd = data(f);
QFixed newContentsWidth;
@@ -2165,8 +2157,8 @@ QRectF QTextDocumentLayoutPrivate::layoutFrame(QTextFrame *f, int layoutFrom, in
layoutStruct.maximumWidth = QFIXED_MAX;
layoutStruct.fullLayout = fullLayout || (fd->oldContentsWidth != newContentsWidth);
layoutStruct.updateRect = QRectF(QPointF(0, 0), QSizeF(qreal(INT_MAX), qreal(INT_MAX)));
- LDEBUG << "layoutStruct: x_left" << layoutStruct.x_left << "x_right" << layoutStruct.x_right
- << "fullLayout" << layoutStruct.fullLayout;
+ qCDebug(lcLayout) << "layoutStruct: x_left" << layoutStruct.x_left << "x_right" << layoutStruct.x_right
+ << "fullLayout" << layoutStruct.fullLayout;
fd->oldContentsWidth = newContentsWidth;
layoutStruct.pageHeight = QFixed::fromReal(document->pageSize().height());
@@ -2220,7 +2212,7 @@ QRectF QTextDocumentLayoutPrivate::layoutFrame(QTextFrame *f, int layoutFrom, in
void QTextDocumentLayoutPrivate::layoutFlow(QTextFrame::Iterator it, QTextLayoutStruct *layoutStruct,
int layoutFrom, int layoutTo, QFixed width)
{
- LDEBUG << "layoutFlow from=" << layoutFrom << "to=" << layoutTo;
+ qCDebug(lcLayout) << "layoutFlow from=" << layoutFrom << "to=" << layoutTo;
QTextFrameData *fd = data(layoutStruct->frame);
fd->currentLayoutStruct = layoutStruct;
@@ -2578,9 +2570,8 @@ void QTextDocumentLayoutPrivate::layoutBlock(const QTextBlock &bl, int blockPosi
QTextLayout *tl = bl.layout();
const int blockLength = bl.length();
- LDEBUG << "layoutBlock from=" << layoutFrom << "to=" << layoutTo;
-
-// qDebug() << "layoutBlock; width" << layoutStruct->x_right - layoutStruct->x_left << "(maxWidth is btw" << tl->maximumWidth() << ')';
+ qCDebug(lcLayout) << "layoutBlock from=" << layoutFrom << "to=" << layoutTo
+ << "; width" << layoutStruct->x_right - layoutStruct->x_left << "(maxWidth is btw" << tl->maximumWidth() << ')';
if (previousBlockFormat) {
qreal margin = qMax(blockFormat.topMargin(), previousBlockFormat->bottomMargin());
@@ -2612,7 +2603,7 @@ void QTextDocumentLayoutPrivate::layoutBlock(const QTextBlock &bl, int blockPosi
// force relayout if we cross a page boundary
|| (layoutStruct->pageHeight != QFIXED_MAX && layoutStruct->absoluteY() + QFixed::fromReal(tl->boundingRect().height()) > layoutStruct->pageBottom)) {
- LDEBUG << " do layout";
+ qCDebug(lcLayout) << "do layout";
QTextOption option = docPrivate->defaultTextOption;
option.setTextDirection(dir);
option.setTabs( blockFormat.tabPositions() );
@@ -2709,7 +2700,8 @@ void QTextDocumentLayoutPrivate::layoutBlock(const QTextBlock &bl, int blockPosi
qreal(q->paintDevice()->logicalDpiY()) / qreal(qt_defaultDpi()) : 1;
getLineHeightParams(blockFormat, line, scaling, &lineAdjustment, &lineBreakHeight, &lineHeight, &lineBottom);
- if (layoutStruct->pageHeight > 0 && layoutStruct->absoluteY() + lineBreakHeight > layoutStruct->pageBottom) {
+ while (layoutStruct->pageHeight > 0 && layoutStruct->absoluteY() + lineBreakHeight > layoutStruct->pageBottom &&
+ layoutStruct->pageHeight >= lineBreakHeight) {
layoutStruct->newPage();
floatMargins(layoutStruct->y, layoutStruct, &left, &right);
@@ -2740,7 +2732,7 @@ void QTextDocumentLayoutPrivate::layoutBlock(const QTextBlock &bl, int blockPosi
const int cnt = tl->lineCount();
QFixed bottom;
for (int i = 0; i < cnt; ++i) {
- LDEBUG << "going to move text line" << i;
+ qCDebug(lcLayout) << "going to move text line" << i;
QTextLine line = tl->lineAt(i);
layoutStruct->contentsWidth
= qMax(layoutStruct->contentsWidth, QFixed::fromReal(line.x() + tl->lineAt(i).naturalTextWidth()) + totalRightMargin);
@@ -3049,18 +3041,12 @@ void QTextDocumentLayout::resizeInlineObject(QTextInlineObject item, int posInDo
QSizeF inlineSize = (pos == QTextFrameFormat::InFlow ? intrinsic : QSizeF(0, 0));
item.setWidth(inlineSize.width());
- QFontMetrics m(f.font());
- switch (f.verticalAlignment())
- {
- case QTextCharFormat::AlignMiddle:
- item.setDescent(inlineSize.height() / 2);
- item.setAscent(inlineSize.height() / 2);
- break;
- case QTextCharFormat::AlignBaseline:
- item.setDescent(m.descent());
- item.setAscent(inlineSize.height() - m.descent());
- break;
- default:
+ if (f.verticalAlignment() == QTextCharFormat::AlignMiddle) {
+ QFontMetrics m(f.font());
+ qreal halfX = m.xHeight()/2.;
+ item.setAscent((inlineSize.height() + halfX) / 2.);
+ item.setDescent((inlineSize.height() - halfX) / 2.);
+ } else {
item.setDescent(0);
item.setAscent(inlineSize.height());
}
diff --git a/src/gui/text/qtextdocumentwriter.cpp b/src/gui/text/qtextdocumentwriter.cpp
index 731aaf1fcf..42e623153a 100644
--- a/src/gui/text/qtextdocumentwriter.cpp
+++ b/src/gui/text/qtextdocumentwriter.cpp
@@ -41,7 +41,9 @@
#include <QtCore/qfile.h>
#include <QtCore/qbytearray.h>
#include <QtCore/qfileinfo.h>
+#if QT_CONFIG(textcodec)
#include <QtCore/qtextcodec.h>
+#endif
#include <QtCore/qtextstream.h>
#include <QtCore/qdebug.h>
#include "qtextdocument.h"
@@ -63,7 +65,7 @@ public:
QByteArray format;
QIODevice *device;
bool deleteDevice;
-#ifndef QT_NO_TEXTCODEC
+#if QT_CONFIG(textcodec)
QTextCodec *codec;
#endif
@@ -104,7 +106,7 @@ public:
QTextDocumentWriterPrivate::QTextDocumentWriterPrivate(QTextDocumentWriter *qq)
: device(0),
deleteDevice(false),
-#ifndef QT_NO_TEXTCODEC
+#if QT_CONFIG(textcodec)
codec(QTextCodec::codecForName("utf-8")),
#endif
q(qq)
@@ -204,8 +206,8 @@ void QTextDocumentWriter::setDevice (QIODevice *device)
}
/*!
- Returns the device currently assigned, or 0 if no device has been
- assigned.
+ Returns the device currently assigned, or \nullptr if no device
+ has been assigned.
*/
QIODevice *QTextDocumentWriter::device () const
{
@@ -258,7 +260,7 @@ bool QTextDocumentWriter::write(const QTextDocument *document)
#ifndef QT_NO_TEXTODFWRITER
if (format == "odf" || format == "opendocumentformat" || format == "odt") {
QTextOdfWriter writer(*document, d->device);
-#ifndef QT_NO_TEXTCODEC
+#if QT_CONFIG(textcodec)
writer.setCodec(d->codec);
#endif
return writer.writeAll();
@@ -268,11 +270,11 @@ bool QTextDocumentWriter::write(const QTextDocument *document)
#ifndef QT_NO_TEXTHTMLPARSER
if (format == "html" || format == "htm") {
if (!d->device->isWritable() && ! d->device->open(QIODevice::WriteOnly)) {
- qWarning("QTextDocumentWriter::write: the device can not be opened for writing");
+ qWarning("QTextDocumentWriter::write: the device cannot be opened for writing");
return false;
}
QTextStream ts(d->device);
-#ifndef QT_NO_TEXTCODEC
+#if QT_CONFIG(textcodec)
ts.setCodec(d->codec);
ts << document->toHtml(d->codec->name());
#endif
@@ -282,11 +284,11 @@ bool QTextDocumentWriter::write(const QTextDocument *document)
#endif
if (format == "txt" || format == "plaintext") {
if (!d->device->isWritable() && ! d->device->open(QIODevice::WriteOnly)) {
- qWarning("QTextDocumentWriter::write: the device can not be opened for writing");
+ qWarning("QTextDocumentWriter::write: the device cannot be opened for writing");
return false;
}
QTextStream ts(d->device);
-#ifndef QT_NO_TEXTCODEC
+#if QT_CONFIG(textcodec)
ts.setCodec(d->codec);
#endif
ts << document->toPlainText();
@@ -317,7 +319,7 @@ bool QTextDocumentWriter::write(const QTextDocumentFragment &fragment)
uses UTF-8.
*/
-#ifndef QT_NO_TEXTCODEC
+#if QT_CONFIG(textcodec)
void QTextDocumentWriter::setCodec(QTextCodec *codec)
{
if (codec == 0)
@@ -330,7 +332,7 @@ void QTextDocumentWriter::setCodec(QTextCodec *codec)
/*!
Returns the codec that is currently assigned to the writer.
*/
-#ifndef QT_NO_TEXTCODEC
+#if QT_CONFIG(textcodec)
QTextCodec *QTextDocumentWriter::codec() const
{
return d->codec;
diff --git a/src/gui/text/qtextdocumentwriter.h b/src/gui/text/qtextdocumentwriter.h
index 0502bf1a96..4a57b181b4 100644
--- a/src/gui/text/qtextdocumentwriter.h
+++ b/src/gui/text/qtextdocumentwriter.h
@@ -70,7 +70,7 @@ public:
bool write(const QTextDocument *document);
bool write(const QTextDocumentFragment &fragment);
-#ifndef QT_NO_TEXTCODEC
+#if QT_CONFIG(textcodec)
void setCodec(QTextCodec *codec);
QTextCodec *codec() const;
#endif
diff --git a/src/gui/text/qtextengine.cpp b/src/gui/text/qtextengine.cpp
index 4e9b00f9c9..2616a42022 100644
--- a/src/gui/text/qtextengine.cpp
+++ b/src/gui/text/qtextengine.cpp
@@ -252,8 +252,6 @@ struct QBidiAlgorithm {
void initScriptAnalysisAndIsolatePairs(Vector<IsolatePair> &isolatePairs)
{
- isolatePairs.append({ -1, length }); // treat the whole string as one isolate
-
int isolateStack[128];
int isolateLevel = 0;
// load directions of string, and determine isolate pairs
@@ -304,6 +302,14 @@ struct QBidiAlgorithm {
case QChar::DirS:
case QChar::DirB:
analysis[pos].bidiFlags = QScriptAnalysis::BidiResetToParagraphLevel;
+ if (uc == QChar::ParagraphSeparator) {
+ // close all open isolates as we start a new paragraph
+ while (isolateLevel > 0) {
+ --isolateLevel;
+ if (isolateLevel < 128)
+ isolatePairs[isolateStack[isolateLevel]].end = pos;
+ }
+ }
break;
default:
break;
@@ -434,21 +440,21 @@ struct QBidiAlgorithm {
doEmbed(true, true, false);
break;
case QChar::DirLRI:
- ++isolatePairPosition;
Q_ASSERT(isolatePairs.at(isolatePairPosition).start == i);
doEmbed(false, false, true);
+ ++isolatePairPosition;
break;
case QChar::DirRLI:
- ++isolatePairPosition;
Q_ASSERT(isolatePairs.at(isolatePairPosition).start == i);
doEmbed(true, false, true);
+ ++isolatePairPosition;
break;
case QChar::DirFSI: {
- ++isolatePairPosition;
const auto &pair = isolatePairs.at(isolatePairPosition);
Q_ASSERT(pair.start == i);
bool isRtl = QStringView(text + pair.start + 1, pair.end - pair.start - 1).isRightToLeft();
doEmbed(isRtl, false, true);
+ ++isolatePairPosition;
break;
}
@@ -492,16 +498,24 @@ struct QBidiAlgorithm {
analysis[i].bidiDirection = (level & 1) ? QChar::DirR : QChar::DirL;
break;
case QChar::DirB:
- // paragraph separator, go down to base direction
- appendRun(i - 1);
- while (stack.counter > 1) {
- // there might be remaining isolates on the stack that are missing a PDI. Those need to get
- // a continuation indicating to take the eos from the end of the string (ie. the paragraph level)
- const auto &t = stack.top();
- if (t.isIsolate) {
- runs[t.runBeforeIsolate].continuation = -2;
+ // paragraph separator, go down to base direction, reset all state
+ if (text[i].unicode() == QChar::ParagraphSeparator) {
+ appendRun(i - 1);
+ while (stack.counter > 1) {
+ // there might be remaining isolates on the stack that are missing a PDI. Those need to get
+ // a continuation indicating to take the eos from the end of the string (ie. the paragraph level)
+ const auto &t = stack.top();
+ if (t.isIsolate) {
+ runs[t.runBeforeIsolate].continuation = -2;
+ }
+ --stack.counter;
}
- --stack.counter;
+ continuationFrom = -1;
+ lastRunWithContent = -1;
+ validIsolateCount = 0;
+ overflowIsolateCount = 0;
+ overflowEmbeddingCount = 0;
+ level = baseLevel;
}
break;
default:
@@ -1094,6 +1108,22 @@ struct QBidiAlgorithm {
resolveImplicitLevels(runs);
}
+ BIDI_DEBUG() << "Rule L1:";
+ // Rule L1:
+ bool resetLevel = true;
+ for (int i = length - 1; i >= 0; --i) {
+ if (analysis[i].bidiFlags & QScriptAnalysis::BidiResetToParagraphLevel) {
+ BIDI_DEBUG() << "resetting pos" << i << "to baselevel";
+ analysis[i].bidiLevel = baseLevel;
+ resetLevel = true;
+ } else if (resetLevel && analysis[i].bidiFlags & QScriptAnalysis::BidiMaybeResetToParagraphLevel) {
+ BIDI_DEBUG() << "resetting pos" << i << "to baselevel (maybereset flag)";
+ analysis[i].bidiLevel = baseLevel;
+ } else {
+ resetLevel = false;
+ }
+ }
+
// set directions for BN to the minimum of adjacent chars
// This makes is possible to be conformant with the Bidi algorithm even though we don't
// remove BN and explicit embedding chars from the stream of characters to reorder
@@ -1125,22 +1155,6 @@ struct QBidiAlgorithm {
}
}
- BIDI_DEBUG() << "Rule L1:";
- // Rule L1:
- bool resetLevel = true;
- for (int i = length - 1; i >= 0; --i) {
- if (analysis[i].bidiFlags & QScriptAnalysis::BidiResetToParagraphLevel) {
- BIDI_DEBUG() << "resetting pos" << i << "to baselevel";
- analysis[i].bidiLevel = baseLevel;
- resetLevel = true;
- } else if (resetLevel && analysis[i].bidiFlags & QScriptAnalysis::BidiMaybeResetToParagraphLevel) {
- BIDI_DEBUG() << "resetting pos" << i << "to baselevel (maybereset flag)";
- analysis[i].bidiLevel = baseLevel;
- } else {
- resetLevel = false;
- }
- }
-
if (BidiDebugEnabled) {
BIDI_DEBUG() << "final resolved levels:";
for (int i = 0; i < length; ++i)
@@ -1398,11 +1412,12 @@ void QTextEngine::shapeText(int item) const
#ifndef QT_NO_RAWFONT
if (useRawFont) {
QTextCharFormat f = format(&si);
- kerningEnabled = f.fontKerning();
+ QFont font = f.font();
+ kerningEnabled = font.kerning();
shapingEnabled = QFontEngine::scriptRequiresOpenType(QChar::Script(si.analysis.script))
- || (f.fontStyleStrategy() & QFont::PreferNoShaping) == 0;
- wordSpacing = QFixed::fromReal(f.fontWordSpacing());
- letterSpacing = QFixed::fromReal(f.fontLetterSpacing());
+ || (font.styleStrategy() & QFont::PreferNoShaping) == 0;
+ wordSpacing = QFixed::fromReal(font.wordSpacing());
+ letterSpacing = QFixed::fromReal(font.letterSpacing());
letterSpacingIsAbsolute = true;
} else
#endif
@@ -1739,7 +1754,7 @@ int QTextEngine::shapeTextWithHarfbuzzNG(const QScriptItem &si,
#ifdef Q_OS_DARWIN
if (actualFontEngine->type() == QFontEngine::Mac) {
- if (actualFontEngine->fontDef.stretch != 100) {
+ if (actualFontEngine->fontDef.stretch != 100 && actualFontEngine->fontDef.stretch != QFont::AnyStretch) {
QFixed stretch = QFixed(int(actualFontEngine->fontDef.stretch)) / QFixed(100);
for (uint i = 0; i < num_glyphs; ++i)
g.advances[i] *= stretch;
@@ -1953,7 +1968,9 @@ const QCharAttributes *QTextEngine::attributes() const
QUnicodeTools::initCharAttributes(reinterpret_cast<const ushort *>(layoutData->string.constData()),
layoutData->string.length(),
scriptItems.data(), scriptItems.size(),
- (QCharAttributes *)layoutData->memory);
+ (QCharAttributes *)layoutData->memory,
+ QUnicodeTools::CharAttributeOptions(QUnicodeTools::DefaultOptionsCompat
+ | QUnicodeTools::HangulLineBreakTailoring));
layoutData->haveCharAttributes = true;
@@ -1962,19 +1979,28 @@ const QCharAttributes *QTextEngine::attributes() const
void QTextEngine::shape(int item) const
{
- if (layoutData->items.at(item).analysis.flags == QScriptAnalysis::Object) {
+ auto &li = layoutData->items[item];
+ if (li.analysis.flags == QScriptAnalysis::Object) {
ensureSpace(1);
if (block.docHandle()) {
docLayout()->resizeInlineObject(QTextInlineObject(item, const_cast<QTextEngine *>(this)),
- layoutData->items[item].position + block.position(),
- format(&layoutData->items[item]));
+ li.position + block.position(),
+ format(&li));
+ }
+ // fix log clusters to point to the previous glyph, as the object doesn't have a glyph of it's own.
+ // This is required so that all entries in the array get initialized and are ordered correctly.
+ if (layoutData->logClustersPtr) {
+ ushort *lc = logClusters(&li);
+ *lc = (lc != layoutData->logClustersPtr) ? lc[-1] : 0;
}
- } else if (layoutData->items.at(item).analysis.flags == QScriptAnalysis::Tab) {
+ } else if (li.analysis.flags == QScriptAnalysis::Tab) {
// set up at least the ascent/descent/leading of the script item for the tab
- fontEngine(layoutData->items[item],
- &layoutData->items[item].ascent,
- &layoutData->items[item].descent,
- &layoutData->items[item].leading);
+ fontEngine(li, &li.ascent, &li.descent, &li.leading);
+ // see the comment above
+ if (layoutData->logClustersPtr) {
+ ushort *lc = logClusters(&li);
+ *lc = (lc != layoutData->logClustersPtr) ? lc[-1] : 0;
+ }
} else {
shapeText(item);
}
@@ -2063,8 +2089,6 @@ void QTextEngine::itemize() const
analysis->flags = QScriptAnalysis::Object;
break;
case QChar::LineSeparator:
- if (analysis->bidiLevel % 2)
- --analysis->bidiLevel;
analysis->flags = QScriptAnalysis::LineOrParagraphSeparator;
if (option.flags() & QTextOption::ShowLineAndParagraphSeparators) {
const int offset = uc - string;
@@ -3187,6 +3211,16 @@ QString QTextEngine::elidedText(Qt::TextElideMode mode, const QFixed &width, int
QChar ellipsisChar(0x2026);
+ // We only want to use the ellipsis character if it is from the main
+ // font (not one of the fallbacks), since using a fallback font
+ // will affect the metrics of the text, potentially causing it to shift
+ // when it is being elided.
+ if (engine->type() == QFontEngine::Multi) {
+ QFontEngineMulti *multiEngine = static_cast<QFontEngineMulti *>(engine);
+ multiEngine->ensureEngineAt(0);
+ engine = multiEngine->engine(0);
+ }
+
glyph_t glyph = engine->glyphIndex(ellipsisChar.unicode());
QGlyphLayout glyphs;
diff --git a/src/gui/text/qtextengine_p.h b/src/gui/text/qtextengine_p.h
index e9187ea605..fddda7f2f8 100644
--- a/src/gui/text/qtextengine_p.h
+++ b/src/gui/text/qtextengine_p.h
@@ -304,8 +304,8 @@ class QTextItemInt : public QTextItem
{
public:
inline QTextItemInt()
- : justified(false), underlineStyle(QTextCharFormat::NoUnderline), num_chars(0), chars(0),
- logClusters(0), f(0), fontEngine(0)
+ : justified(false), underlineStyle(QTextCharFormat::NoUnderline), num_chars(0), chars(nullptr),
+ logClusters(nullptr), f(nullptr), fontEngine(nullptr)
{}
QTextItemInt(const QScriptItem &si, QFont *font, const QTextCharFormat &format = QTextCharFormat());
QTextItemInt(const QGlyphLayout &g, QFont *font, const QChar *chars, int numChars, QFontEngine *fe,
@@ -335,7 +335,7 @@ public:
struct QScriptItem
{
- Q_DECL_CONSTEXPR QScriptItem(int p, QScriptAnalysis a) Q_DECL_NOTHROW
+ Q_DECL_CONSTEXPR QScriptItem(int p, QScriptAnalysis a) noexcept
: position(p), analysis(a),
num_glyphs(0), descent(-1), ascent(-1), leading(-1), width(-1),
glyph_data_offset(0) {}
@@ -348,7 +348,7 @@ struct QScriptItem
QFixed leading;
QFixed width;
int glyph_data_offset;
- Q_DECL_CONSTEXPR QFixed height() const Q_DECL_NOTHROW { return ascent + descent; }
+ Q_DECL_CONSTEXPR QFixed height() const noexcept { return ascent + descent; }
private:
friend class QVector<QScriptItem>;
QScriptItem() {}; // for QVector, don't use
@@ -484,7 +484,7 @@ public:
return end - si->position;
}
- QFontEngine *fontEngine(const QScriptItem &si, QFixed *ascent = 0, QFixed *descent = 0, QFixed *leading = 0) const;
+ QFontEngine *fontEngine(const QScriptItem &si, QFixed *ascent = nullptr, QFixed *descent = nullptr, QFixed *leading = nullptr) const;
QFont font(const QScriptItem &si) const;
inline QFont font() const { return fnt; }
@@ -530,7 +530,7 @@ public:
inline QTextFormatCollection *formatCollection() const {
if (block.docHandle())
return block.docHandle()->formatCollection();
- return specialData ? specialData->formatCollection.data() : 0;
+ return specialData ? specialData->formatCollection.data() : nullptr;
}
QTextCharFormat format(const QScriptItem *si) const;
inline QAbstractTextDocumentLayout *docLayout() const {
@@ -553,8 +553,8 @@ private:
mutable int prevPosition;
mutable int prevLength;
inline void reset() {
- prevFontEngine = 0;
- prevScaledFontEngine = 0;
+ prevFontEngine = nullptr;
+ prevScaledFontEngine = nullptr;
prevScript = -1;
prevPosition = -1;
prevLength = -1;
@@ -684,7 +684,7 @@ Q_DECLARE_TYPEINFO(QTextEngine::ItemDecoration, Q_MOVABLE_TYPE);
struct QTextLineItemIterator
{
QTextLineItemIterator(QTextEngine *eng, int lineNum, const QPointF &pos = QPointF(),
- const QTextLayout::FormatRange *_selection = 0);
+ const QTextLayout::FormatRange *_selection = nullptr);
inline bool atEnd() const { return logicalItem >= nItems - 1; }
inline bool atBeginning() const { return logicalItem <= 0; }
diff --git a/src/gui/text/qtextformat.cpp b/src/gui/text/qtextformat.cpp
index 4957da1908..4a2985f74c 100644
--- a/src/gui/text/qtextformat.cpp
+++ b/src/gui/text/qtextformat.cpp
@@ -361,6 +361,12 @@ void QTextFormatPrivate::recalcFont() const
case QTextFormat::FontFamily:
f.setFamily(props.at(i).value.toString());
break;
+ case QTextFormat::FontFamilies:
+ f.setFamilies(props.at(i).value.toStringList());
+ break;
+ case QTextFormat::FontStyleName:
+ f.setStyleName(props.at(i).value.toString());
+ break;
case QTextFormat::FontPointSize:
f.setPointSizeF(props.at(i).value.toReal());
break;
@@ -562,6 +568,8 @@ Q_GUI_EXPORT QDataStream &operator>>(QDataStream &stream, QTextFormat &fmt)
Character properties
\value FontFamily
+ \value FontFamilies
+ \value FontStyleName
\value FontPointSize
\value FontPixelSize
\value FontSizeAdjustment Specifies the change in size given to the fontsize already set using
@@ -645,6 +653,7 @@ Q_GUI_EXPORT QDataStream &operator>>(QDataStream &stream, QTextFormat &fmt)
\value ImageName
\value ImageWidth
\value ImageHeight
+ \value ImageQuality
Selection properties
@@ -1390,6 +1399,41 @@ QTextCharFormat::QTextCharFormat(const QTextFormat &fmt)
\sa font()
*/
+/*!
+ \fn void QTextCharFormat::setFontFamilies(const QStringList &families)
+ \since 5.13
+
+ Sets the text format's font \a families.
+
+ \sa setFont()
+*/
+
+/*!
+ \fn QStringList QTextCharFormat::fontFamilies() const
+ \since 5.13
+
+ Returns the text format's font families.
+
+ \sa font()
+*/
+
+/*!
+ \fn void QTextCharFormat::setFontStyleName(const QString &styleName)
+ \since 5.13
+
+ Sets the text format's font \a styleName.
+
+ \sa setFont(), QFont::setStyleName()
+*/
+
+/*!
+ \fn QStringList QTextCharFormat::fontStyleName() const
+ \since 5.13
+
+ Returns the text format's font style name.
+
+ \sa font(), QFont::styleName()
+*/
/*!
\fn void QTextCharFormat::setFontPointSize(qreal size)
@@ -1743,6 +1787,7 @@ void QTextCharFormat::setUnderlineStyle(UnderlineStyle style)
*/
+#if QT_DEPRECATED_SINCE(5, 13)
/*!
\fn void QTextCharFormat::setAnchorName(const QString &name)
\obsolete
@@ -1753,6 +1798,7 @@ void QTextCharFormat::setUnderlineStyle(UnderlineStyle style)
hyperlink, the destination must be set with setAnchorHref() and
the anchor must be enabled with setAnchor().
*/
+#endif
/*!
\fn void QTextCharFormat::setAnchorNames(const QStringList &names)
@@ -1763,6 +1809,7 @@ void QTextCharFormat::setUnderlineStyle(UnderlineStyle style)
the anchor must be enabled with setAnchor().
*/
+#if QT_DEPRECATED_SINCE(5, 13)
/*!
\fn QString QTextCharFormat::anchorName() const
\obsolete
@@ -1782,6 +1829,7 @@ QString QTextCharFormat::anchorName() const
return QString();
return prop.toString();
}
+#endif
/*!
\fn QStringList QTextCharFormat::anchorNames() const
@@ -1919,6 +1967,11 @@ void QTextCharFormat::setFont(const QFont &font, FontPropertiesInheritanceBehavi
if (mask & QFont::FamilyResolved)
setFontFamily(font.family());
+ if (mask & QFont::FamiliesResolved)
+ setFontFamilies(font.families());
+ if (mask & QFont::StyleNameResolved)
+ setFontStyleName(font.styleName());
+
if (mask & QFont::SizeResolved) {
const qreal pointSize = font.pointSizeF();
if (pointSize > 0) {
@@ -2251,7 +2304,7 @@ QList<QTextOption::Tab> QTextBlockFormat::tabPositions() const
\fn void QTextBlockFormat::setHeadingLevel(int level)
\since 5.12
- Sets the paragraph's heading level, where 1 is the highest-level heading
+ Sets the paragraph's heading \a level, where 1 is the highest-level heading
type (usually with the largest possible heading font size), and increasing
values are progressively deeper into the document (and usually with smaller
font sizes). For example when reading an HTML H1 tag, the heading level is
diff --git a/src/gui/text/qtextformat.h b/src/gui/text/qtextformat.h
index a8e573d5a4..80d8e82694 100644
--- a/src/gui/text/qtextformat.h
+++ b/src/gui/text/qtextformat.h
@@ -188,6 +188,8 @@ public:
FontStyleStrategy = 0x1FE4,
FontKerning = 0x1FE5,
FontHintingPreference = 0x1FE6,
+ FontFamilies = 0x1FE7,
+ FontStyleName = 0x1FE8,
FontFamily = 0x2000,
FontPointSize = 0x2001,
FontSizeAdjustment = 0x2002,
@@ -428,6 +430,16 @@ public:
inline QString fontFamily() const
{ return stringProperty(FontFamily); }
+ inline void setFontFamilies(const QStringList &families)
+ { setProperty(FontFamilies, QVariant(families)); }
+ inline QVariant fontFamilies() const
+ { return property(FontFamilies); }
+
+ inline void setFontStyleName(const QString &styleName)
+ { setProperty(FontStyleName, styleName); }
+ inline QVariant fontStyleName() const
+ { return property(FontStyleName); }
+
inline void setFontPointSize(qreal size)
{ setProperty(FontPointSize, size); }
inline qreal fontPointSize() const
@@ -540,9 +552,13 @@ public:
inline QString anchorHref() const
{ return stringProperty(AnchorHref); }
+#if QT_DEPRECATED_SINCE(5, 13)
+ QT_DEPRECATED_X("Use setAnchorNames() instead")
inline void setAnchorName(const QString &name)
{ setAnchorNames(QStringList(name)); }
+ QT_DEPRECATED_X("Use anchorNames() instead")
QString anchorName() const;
+#endif
inline void setAnchorNames(const QStringList &names)
{ setProperty(AnchorName, names); }
diff --git a/src/gui/text/qtextformat_p.h b/src/gui/text/qtextformat_p.h
index 3557c17a97..001a243e84 100644
--- a/src/gui/text/qtextformat_p.h
+++ b/src/gui/text/qtextformat_p.h
@@ -104,7 +104,7 @@ public:
private:
QFont defaultFnt;
- Q_DISABLE_COPY(QTextFormatCollection)
+ Q_DISABLE_COPY_MOVE(QTextFormatCollection)
};
QT_END_NAMESPACE
diff --git a/src/gui/text/qtexthtmlparser.cpp b/src/gui/text/qtexthtmlparser.cpp
index 4be800b251..adc3b138f7 100644
--- a/src/gui/text/qtexthtmlparser.cpp
+++ b/src/gui/text/qtexthtmlparser.cpp
@@ -40,7 +40,6 @@
#include "qtexthtmlparser_p.h"
#include <qbytearray.h>
-#include <qtextcodec.h>
#include <qstack.h>
#include <qdebug.h>
#include <qthread.h>
@@ -862,7 +861,8 @@ QString QTextHtmlParser::parseWord()
++pos;
while (pos < len) {
QChar c = txt.at(pos++);
- if (c == QLatin1Char('\''))
+ // Allow for escaped single quotes as they may be part of the string
+ if (c == QLatin1Char('\'') && (txt.length() > 1 && txt.at(pos - 2) != QLatin1Char('\\')))
break;
else
word += c;
@@ -1544,7 +1544,7 @@ void QTextHtmlParser::applyAttributes(const QStringList &attributes)
if (key == QLatin1String("href"))
node->charFormat.setAnchorHref(value);
else if (key == QLatin1String("name"))
- node->charFormat.setAnchorName(value);
+ node->charFormat.setAnchorNames({value});
break;
case Html_img:
if (key == QLatin1String("src") || key == QLatin1String("source")) {
@@ -1684,7 +1684,7 @@ void QTextHtmlParser::applyAttributes(const QStringList &attributes)
node->charFormat.setToolTip(value);
} else if (key == QLatin1String("id")) {
node->charFormat.setAnchor(true);
- node->charFormat.setAnchorName(value);
+ node->charFormat.setAnchorNames({value});
}
}
diff --git a/src/gui/text/qtextimagehandler_p.h b/src/gui/text/qtextimagehandler_p.h
index 339ef0af4f..fafd394ad3 100644
--- a/src/gui/text/qtextimagehandler_p.h
+++ b/src/gui/text/qtextimagehandler_p.h
@@ -65,7 +65,7 @@ class Q_GUI_EXPORT QTextImageHandler : public QObject,
Q_OBJECT
Q_INTERFACES(QTextObjectInterface)
public:
- explicit QTextImageHandler(QObject *parent = 0);
+ explicit QTextImageHandler(QObject *parent = nullptr);
virtual QSizeF intrinsicSize(QTextDocument *doc, int posInDocument, const QTextFormat &format) override;
virtual void drawObject(QPainter *p, const QRectF &rect, QTextDocument *doc, int posInDocument, const QTextFormat &format) override;
diff --git a/src/gui/text/qtextlayout.cpp b/src/gui/text/qtextlayout.cpp
index ca6866d836..a3e194f835 100644
--- a/src/gui/text/qtextlayout.cpp
+++ b/src/gui/text/qtextlayout.cpp
@@ -344,6 +344,8 @@ QTextLayout::QTextLayout(const QString& text)
}
/*!
+ \since 5.13
+ \fn QTextLayout::QTextLayout(const QString &text, const QFont &font, const QPaintDevice *paintdevice)
Constructs a text layout to lay out the given \a text with the specified
\a font.
@@ -351,11 +353,20 @@ QTextLayout::QTextLayout(const QString& text)
the paint device, \a paintdevice. If \a paintdevice is 0 the
calculations will be done in screen metrics.
*/
-QTextLayout::QTextLayout(const QString& text, const QFont &font, QPaintDevice *paintdevice)
+
+#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
+/*!
+ \fn QTextLayout::QTextLayout(const QString &text, const QFont &font, QPaintDevice *paintdevice)
+ \obsolete
+ Identical to QTextLayout::QTextLayout(const QString &text, const QFont &font, const QPaintDevice *paintdevice)
+*/
+
+QTextLayout::QTextLayout(const QString &text, const QFont &font, QPaintDevice *paintdevice)
+#else
+QTextLayout::QTextLayout(const QString &text, const QFont &font, const QPaintDevice *paintdevice)
+#endif
{
- QFont f(font);
- if (paintdevice)
- f = QFont(font, paintdevice);
+ const QFont f(paintdevice ? QFont(font, paintdevice) : font);
d = new QTextEngine((text.isNull() ? (const QString&)QString::fromLatin1("") : text), f);
}
@@ -1127,8 +1138,6 @@ void QTextLayout::draw(QPainter *p, const QPointF &pos, const QVector<FormatRang
QPainterPath textDoneRegion;
for (int i = 0; i < selections.size(); ++i) {
FormatRange selection = selections.at(i);
- const QBrush bg = selection.format.background();
-
QPainterPath region;
region.setFillRule(Qt::WindingFill);
@@ -1823,6 +1832,9 @@ void QTextLine::layout_helper(int maxGlyphs)
lbh.logClusters = eng->layoutData->logClustersPtr;
lbh.previousGlyph = 0;
+ bool hasInlineObject = false;
+ QFixed maxInlineObjectHeight = 0;
+
while (newItem < eng->layoutData->items.size()) {
lbh.resetRightBearing();
lbh.softHyphenWidth = 0;
@@ -1851,8 +1863,11 @@ void QTextLine::layout_helper(int maxGlyphs)
lbh.tmpData.leading = qMax(lbh.tmpData.leading + lbh.tmpData.ascent,
current.leading + current.ascent) - qMax(lbh.tmpData.ascent,
current.ascent);
- lbh.tmpData.ascent = qMax(lbh.tmpData.ascent, current.ascent);
- lbh.tmpData.descent = qMax(lbh.tmpData.descent, current.descent);
+ if (current.analysis.flags != QScriptAnalysis::Object) {
+ // objects need some special treatment as they can special alignment or be floating
+ lbh.tmpData.ascent = qMax(lbh.tmpData.ascent, current.ascent);
+ lbh.tmpData.descent = qMax(lbh.tmpData.descent, current.descent);
+ }
if (current.analysis.flags == QScriptAnalysis::Tab && (alignment & (Qt::AlignLeft | Qt::AlignRight | Qt::AlignCenter | Qt::AlignJustify))) {
lbh.whiteSpaceOrObject = true;
@@ -1900,9 +1915,18 @@ void QTextLine::layout_helper(int maxGlyphs)
if (eng->block.docHandle()) {
QTextInlineObject inlineObject(item, eng);
- eng->docLayout()->positionInlineObject(inlineObject, eng->block.position() + current.position, inlineObject.format());
+ QTextFormat f = inlineObject.format();
+ eng->docLayout()->positionInlineObject(inlineObject, eng->block.position() + current.position, f);
+ QTextCharFormat::VerticalAlignment valign = f.toCharFormat().verticalAlignment();
+ if (valign != QTextCharFormat::AlignTop && valign != QTextCharFormat::AlignBottom) {
+ lbh.tmpData.ascent = qMax(lbh.tmpData.ascent, current.ascent);
+ lbh.tmpData.descent = qMax(lbh.tmpData.descent, current.descent);
+ }
}
+ hasInlineObject = true;
+ maxInlineObjectHeight = qMax(maxInlineObjectHeight, current.ascent + current.descent);
+
lbh.tmpData.textWidth += current.width;
newItem = item + 1;
@@ -2038,6 +2062,43 @@ found:
line += lbh.tmpData;
}
+ if (hasInlineObject && eng->block.docHandle()) {
+ // position top/bottom aligned inline objects
+ if (maxInlineObjectHeight > line.ascent + line.descent) {
+ // extend line height if required
+ QFixed toAdd = (maxInlineObjectHeight - line.ascent - line.descent)/2;
+ line.ascent += toAdd;
+ line.descent = maxInlineObjectHeight - line.ascent;
+ }
+ int startItem = eng->findItem(line.from);
+ int endItem = eng->findItem(line.from + line.length);
+ if (endItem < 0)
+ endItem = eng->layoutData->items.size();
+ for (int item = startItem; item < endItem; ++item) {
+ QScriptItem &current = eng->layoutData->items[item];
+ if (current.analysis.flags == QScriptAnalysis::Object) {
+ QTextInlineObject inlineObject(item, eng);
+ QTextCharFormat::VerticalAlignment align = inlineObject.format().toCharFormat().verticalAlignment();
+ QFixed height = current.ascent + current.descent;
+ switch (align) {
+ case QTextCharFormat::AlignTop:
+ current.ascent = line.ascent;
+ current.descent = height - line.ascent;
+ break;
+ case QTextCharFormat::AlignBottom:
+ current.descent = line.descent;
+ current.ascent = height - line.descent;
+ break;
+ default:
+ break;
+ }
+ Q_ASSERT(line.ascent >= current.ascent);
+ Q_ASSERT(line.descent >= current.descent);
+ }
+ }
+ }
+
+
LB_DEBUG("line length = %d, ascent=%f, descent=%f, textWidth=%f (spacew=%f)", line.length, line.ascent.toReal(),
line.descent.toReal(), line.textWidth.toReal(), lbh.spaceData.width.toReal());
LB_DEBUG(" : '%s'", eng->layoutData->string.mid(line.from, line.length).toUtf8().data());
@@ -2511,6 +2572,8 @@ void QTextLine::draw(QPainter *p, const QPointF &pos, const QTextLayout::FormatR
QFixed itemY = y - si.ascent;
if (format.verticalAlignment() == QTextCharFormat::AlignTop) {
itemY = y - lineBase;
+ } else if (format.verticalAlignment() == QTextCharFormat::AlignBottom) {
+ itemY = y + line.descent - si.ascent - si.descent;
}
QRectF itemRect(iterator.x.toReal(), itemY.toReal(), iterator.itemWidth.toReal(), si.height().toReal());
@@ -2544,6 +2607,7 @@ void QTextLine::draw(QPainter *p, const QPointF &pos, const QTextLayout::FormatR
Qt::IntersectClip);
else
x /= 2; // Centered
+ p->setFont(f);
p->drawText(QPointF(iterator.x.toReal() + x,
y.toReal()), visualTab);
}
@@ -2617,8 +2681,11 @@ void QTextLine::draw(QPainter *p, const QPointF &pos, const QTextLayout::FormatR
if (c.style() != Qt::NoBrush)
p->setPen(c.color());
QChar visualSpace(si.analysis.flags == QScriptAnalysis::Space ? (ushort)0xb7 : (ushort)0xb0);
+ QFont oldFont = p->font();
+ p->setFont(eng->font(si));
p->drawText(QPointF(iterator.x.toReal(), itemBaseLine.toReal()), visualSpace);
p->setPen(pen);
+ p->setFont(oldFont);
}
}
eng->drawDecorations(p);
diff --git a/src/gui/text/qtextlayout.h b/src/gui/text/qtextlayout.h
index 67bc75a6b8..a29791534e 100644
--- a/src/gui/text/qtextlayout.h
+++ b/src/gui/text/qtextlayout.h
@@ -107,7 +107,19 @@ public:
// does itemization
QTextLayout();
QTextLayout(const QString& text);
- QTextLayout(const QString& text, const QFont &font, QPaintDevice *paintdevice = nullptr);
+#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
+ QTextLayout(const QString &text, const QFont &font, QPaintDevice *paintdevice = nullptr);
+#ifndef Q_QDOC
+ // the template is necessary to make QTextLayout(font,text,nullptr) and QTextLayout(font,text,NULL)
+ // not ambiguous. Implementation detail that should not be documented.
+ template<char = 0>
+#endif
+ QTextLayout(const QString &text, const QFont &font, const QPaintDevice *paintdevice)
+ : QTextLayout(text, font, const_cast<QPaintDevice*>(paintdevice))
+ {}
+#else
+ QTextLayout(const QString &text, const QFont &font, const QPaintDevice *paintdevice = nullptr);
+#endif
QTextLayout(const QTextBlock &b);
~QTextLayout();
diff --git a/src/gui/text/qtextlist.cpp b/src/gui/text/qtextlist.cpp
index bec33d5f4d..5857afa048 100644
--- a/src/gui/text/qtextlist.cpp
+++ b/src/gui/text/qtextlist.cpp
@@ -100,6 +100,7 @@ public:
\sa QTextBlock, QTextListFormat, QTextCursor
*/
+#if QT_DEPRECATED_SINCE(5, 13)
/*!
\fn bool QTextList::isEmpty() const
\obsolete
@@ -111,6 +112,7 @@ public:
\sa count()
*/
+#endif
/*! \internal
*/
diff --git a/src/gui/text/qtextlist.h b/src/gui/text/qtextlist.h
index 3967787f03..cfb9f9456f 100644
--- a/src/gui/text/qtextlist.h
+++ b/src/gui/text/qtextlist.h
@@ -59,8 +59,11 @@ public:
int count() const;
+#if QT_DEPRECATED_SINCE(5, 13)
+ QT_DEPRECATED_X("Use count() instead")
inline bool isEmpty() const
{ return count() == 0; }
+#endif
QTextBlock item(int i) const;
diff --git a/src/gui/text/qtextobject.cpp b/src/gui/text/qtextobject.cpp
index e2130a09d9..9156ee6af4 100644
--- a/src/gui/text/qtextobject.cpp
+++ b/src/gui/text/qtextobject.cpp
@@ -678,7 +678,7 @@ QTextFrame::iterator::iterator(QTextFrame *frame, int block, int begin, int end)
/*!
Copy constructor. Constructs a copy of the \a other iterator.
*/
-QTextFrame::iterator::iterator(const iterator &other) Q_DECL_NOTHROW
+QTextFrame::iterator::iterator(const iterator &other) noexcept
{
f = other.f;
b = other.b;
@@ -691,7 +691,7 @@ QTextFrame::iterator::iterator(const iterator &other) Q_DECL_NOTHROW
Assigns \a other to this iterator and returns a reference to
this iterator.
*/
-QTextFrame::iterator &QTextFrame::iterator::operator=(const iterator &other) Q_DECL_NOTHROW
+QTextFrame::iterator &QTextFrame::iterator::operator=(const iterator &other) noexcept
{
f = other.f;
b = other.b;
@@ -704,8 +704,8 @@ QTextFrame::iterator &QTextFrame::iterator::operator=(const iterator &other) Q_D
#endif
/*!
- Returns the current frame pointed to by the iterator, or 0 if the
- iterator currently points to a block.
+ Returns the current frame pointed to by the iterator, or \nullptr
+ if the iterator currently points to a block.
\sa currentBlock()
*/
@@ -1291,22 +1291,22 @@ QVector<QTextLayout::FormatRange> QTextBlock::textFormats() const
}
/*!
- Returns the text document this text block belongs to, or 0 if the
- text block does not belong to any document.
+ Returns the text document this text block belongs to, or \nullptr
+ if the text block does not belong to any document.
*/
const QTextDocument *QTextBlock::document() const
{
- return p ? p->document() : 0;
+ return p ? p->document() : nullptr;
}
/*!
If the block represents a list item, returns the list that the item belongs
- to; otherwise returns 0.
+ to; otherwise returns \nullptr.
*/
QTextList *QTextBlock::textList() const
{
if (!isValid())
- return 0;
+ return nullptr;
const QTextBlockFormat fmt = blockFormat();
QTextObject *obj = p->document()->objectForFormat(fmt);
diff --git a/src/gui/text/qtextobject.h b/src/gui/text/qtextobject.h
index 067f8473ea..586a593dd2 100644
--- a/src/gui/text/qtextobject.h
+++ b/src/gui/text/qtextobject.h
@@ -151,11 +151,11 @@ public:
public:
iterator(); // ### Qt 6: inline
#if QT_VERSION < QT_VERSION_CHECK(6,0,0)
- iterator(const iterator &o) Q_DECL_NOTHROW; // = default
- iterator &operator=(const iterator &o) Q_DECL_NOTHROW; // = default
- iterator(iterator &&other) Q_DECL_NOTHROW // = default
+ iterator(const iterator &o) noexcept; // = default
+ iterator &operator=(const iterator &o) noexcept; // = default
+ iterator(iterator &&other) noexcept // = default
{ memcpy(static_cast<void *>(this), static_cast<void *>(&other), sizeof(iterator)); }
- iterator &operator=(iterator &&other) Q_DECL_NOTHROW // = default
+ iterator &operator=(iterator &&other) noexcept // = default
{ memcpy(static_cast<void *>(this), static_cast<void *>(&other), sizeof(iterator)); return *this; }
#endif
diff --git a/src/gui/text/qtextobject_p.h b/src/gui/text/qtextobject_p.h
index 81ab023cc3..87c83868da 100644
--- a/src/gui/text/qtextobject_p.h
+++ b/src/gui/text/qtextobject_p.h
@@ -93,7 +93,7 @@ class QTextFramePrivate : public QTextObjectPrivate
Q_DECLARE_PUBLIC(QTextFrame)
public:
QTextFramePrivate(QTextDocument *doc)
- : QTextObjectPrivate(doc), fragment_start(0), fragment_end(0), parentFrame(0), layoutData(0)
+ : QTextObjectPrivate(doc), fragment_start(0), fragment_end(0), parentFrame(nullptr), layoutData(nullptr)
{
}
virtual void fragmentAdded(QChar type, uint fragment);
diff --git a/src/gui/text/qtextodfwriter.cpp b/src/gui/text/qtextodfwriter.cpp
index 5f6a24cc5d..a62e7e425a 100644
--- a/src/gui/text/qtextodfwriter.cpp
+++ b/src/gui/text/qtextodfwriter.cpp
@@ -496,10 +496,12 @@ void QTextOdfWriter::writeFormats(QXmlStreamWriter &writer, const QSet<int> &for
else
writeFrameFormat(writer, textFormat.toFrameFormat(), formatIndex);
break;
+#if QT_DEPRECATED_SINCE(5, 3)
case QTextFormat::TableFormat:
// this case never happens, because TableFormat is a FrameFormat
Q_UNREACHABLE();
break;
+#endif
}
}
@@ -886,26 +888,30 @@ void QTextOdfWriter::tableCellStyleElement(QXmlStreamWriter &writer, const int &
if (hasBorder) {
writer.writeAttribute(foNS, QString::fromLatin1("border"),
pixelToPoint(tableFormatTmp.border()) + QLatin1String(" ")
- + borderStyleName(tableFormatTmp.borderStyle())
- + QLatin1String(" #000000")); //!! HARD-CODING color black
+ + borderStyleName(tableFormatTmp.borderStyle()) + QLatin1String(" ")
+ + tableFormatTmp.borderBrush().color().name(QColor::HexRgb));
}
- qreal padding = format.topPadding();
- if (padding > 0 && padding == format.bottomPadding()
- && padding == format.leftPadding() && padding == format.rightPadding()) {
+ qreal topPadding = format.topPadding();
+ qreal padding = topPadding + tableFormatTmp.cellPadding();
+ if (padding > 0 && topPadding == format.bottomPadding()
+ && topPadding == format.leftPadding() && topPadding == format.rightPadding()) {
writer.writeAttribute(foNS, QString::fromLatin1("padding"), pixelToPoint(padding));
}
else {
if (padding > 0)
writer.writeAttribute(foNS, QString::fromLatin1("padding-top"), pixelToPoint(padding));
- if (format.bottomPadding() > 0)
+ padding = format.bottomPadding() + tableFormatTmp.cellPadding();
+ if (padding > 0)
writer.writeAttribute(foNS, QString::fromLatin1("padding-bottom"),
- pixelToPoint(format.bottomPadding()));
- if (format.leftPadding() > 0)
+ pixelToPoint(padding));
+ padding = format.leftPadding() + tableFormatTmp.cellPadding();
+ if (padding > 0)
writer.writeAttribute(foNS, QString::fromLatin1("padding-left"),
- pixelToPoint(format.leftPadding()));
- if (format.rightPadding() > 0)
+ pixelToPoint(padding));
+ padding = format.rightPadding() + tableFormatTmp.cellPadding();
+ if (padding > 0)
writer.writeAttribute(foNS, QString::fromLatin1("padding-right"),
- pixelToPoint(format.rightPadding()));
+ pixelToPoint(padding));
}
if (format.hasProperty(QTextFormat::TextVerticalAlignment)) {
@@ -957,11 +963,11 @@ bool QTextOdfWriter::writeAll()
m_strategy = new QXmlStreamStrategy(m_device);
if (!m_device->isWritable() && ! m_device->open(QIODevice::WriteOnly)) {
- qWarning("QTextOdfWriter::writeAll: the device can not be opened for writing");
+ qWarning("QTextOdfWriter::writeAll: the device cannot be opened for writing");
return false;
}
QXmlStreamWriter writer(m_strategy->contentStream);
-#ifndef QT_NO_TEXTCODEC
+#if QT_CONFIG(textcodec)
if (m_codec)
writer.setCodec(m_codec);
#endif
diff --git a/src/gui/text/qtexttable.cpp b/src/gui/text/qtexttable.cpp
index 9639c18d2b..39f26d5d42 100644
--- a/src/gui/text/qtexttable.cpp
+++ b/src/gui/text/qtexttable.cpp
@@ -696,18 +696,22 @@ void QTextTable::insertRows(int pos, int num)
int extended = 0;
int insert_before = 0;
if (pos > 0 && pos < d->nRows) {
+ int lastCell = -1;
for (int i = 0; i < d->nCols; ++i) {
int cell = d->grid[pos*d->nCols + i];
if (cell == d->grid[(pos-1)*d->nCols+i]) {
// cell spans the insertion place, extend it
- QTextDocumentPrivate::FragmentIterator it(&p->fragmentMap(), cell);
- QTextCharFormat fmt = c->charFormat(it->format);
- fmt.setTableCellRowSpan(fmt.tableCellRowSpan() + num);
- p->setCharFormat(it.position(), 1, fmt);
+ if (cell != lastCell) {
+ QTextDocumentPrivate::FragmentIterator it(&p->fragmentMap(), cell);
+ QTextCharFormat fmt = c->charFormat(it->format);
+ fmt.setTableCellRowSpan(fmt.tableCellRowSpan() + num);
+ p->setCharFormat(it.position(), 1, fmt);
+ }
extended++;
} else if (!insert_before) {
insert_before = cell;
}
+ lastCell = cell;
}
} else {
insert_before = (pos == 0 ? d->grid[0] : d->fragment_end);
diff --git a/src/gui/text/qtexttable_p.h b/src/gui/text/qtexttable_p.h
index c969e1d5bc..5c05611009 100644
--- a/src/gui/text/qtexttable_p.h
+++ b/src/gui/text/qtexttable_p.h
@@ -61,7 +61,7 @@ class QTextTablePrivate : public QTextFramePrivate
{
Q_DECLARE_PUBLIC(QTextTable)
public:
- QTextTablePrivate(QTextDocument *document) : QTextFramePrivate(document), grid(0), nRows(0), nCols(0), dirty(true), blockFragmentUpdates(false) {}
+ QTextTablePrivate(QTextDocument *document) : QTextFramePrivate(document), grid(nullptr), nRows(0), nCols(0), dirty(true), blockFragmentUpdates(false) {}
~QTextTablePrivate();
static QTextTable *createTable(QTextDocumentPrivate *, int pos, int rows, int cols, const QTextTableFormat &tableFormat);
diff --git a/src/gui/text/qzipreader_p.h b/src/gui/text/qzipreader_p.h
index eed6ee6a62..6fec8d7719 100644
--- a/src/gui/text/qzipreader_p.h
+++ b/src/gui/text/qzipreader_p.h
@@ -79,11 +79,11 @@ public:
struct FileInfo
{
- FileInfo() Q_DECL_NOTHROW
+ FileInfo() noexcept
: isDir(false), isFile(false), isSymLink(false), crc(0), size(0)
{}
- bool isValid() const Q_DECL_NOTHROW { return isDir || isFile || isSymLink; }
+ bool isValid() const noexcept { return isDir || isFile || isSymLink; }
QString filePath;
uint isDir : 1;
@@ -116,7 +116,7 @@ public:
private:
QZipReaderPrivate *d;
- Q_DISABLE_COPY(QZipReader)
+ Q_DISABLE_COPY_MOVE(QZipReader)
};
Q_DECLARE_TYPEINFO(QZipReader::FileInfo, Q_MOVABLE_TYPE);
Q_DECLARE_TYPEINFO(QZipReader::Status, Q_PRIMITIVE_TYPE);
diff --git a/src/gui/text/qzipwriter_p.h b/src/gui/text/qzipwriter_p.h
index 433bbab31e..b3bb5929cf 100644
--- a/src/gui/text/qzipwriter_p.h
+++ b/src/gui/text/qzipwriter_p.h
@@ -108,7 +108,7 @@ public:
void close();
private:
QZipWriterPrivate *d;
- Q_DISABLE_COPY(QZipWriter)
+ Q_DISABLE_COPY_MOVE(QZipWriter)
};
QT_END_NAMESPACE