diff options
Diffstat (limited to 'src/gui/text')
94 files changed, 3132 insertions, 1947 deletions
diff --git a/src/gui/text/qabstractfontengine_p.h b/src/gui/text/qabstractfontengine_p.h index 117a9df..b912230 100644 --- a/src/gui/text/qabstractfontengine_p.h +++ b/src/gui/text/qabstractfontengine_p.h @@ -1,7 +1,6 @@ /**************************************************************************** ** ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** ** This file is part of the QtGui module of the Qt Toolkit. @@ -21,9 +20,10 @@ ** ensure the GNU Lesser General Public License version 2.1 requirements ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. ** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.1, included in the file LGPL_EXCEPTION.txt in this +** package. ** ** If you have questions regarding the use of this file, please contact ** Nokia at qt-info@nokia.com. @@ -91,7 +91,7 @@ public: virtual Type type() const { return Proxy; } virtual const char *name() const { return "proxy engine"; } -#if !defined(Q_WS_X11) && !defined(Q_WS_WIN) && !defined(Q_WS_MAC) +#if !defined(Q_WS_X11) && !defined(Q_WS_WIN) && !defined(Q_WS_MAC) && !defined(Q_OS_SYMBIAN) virtual void draw(QPaintEngine *, qreal, qreal, const QTextItemInt &); #endif diff --git a/src/gui/text/qabstractfontengine_qws.cpp b/src/gui/text/qabstractfontengine_qws.cpp index a58a4cf..6c7c660 100644 --- a/src/gui/text/qabstractfontengine_qws.cpp +++ b/src/gui/text/qabstractfontengine_qws.cpp @@ -1,7 +1,6 @@ /**************************************************************************** ** ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** ** This file is part of the QtGui module of the Qt Toolkit. @@ -21,9 +20,10 @@ ** ensure the GNU Lesser General Public License version 2.1 requirements ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. ** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.1, included in the file LGPL_EXCEPTION.txt in this +** package. ** ** If you have questions regarding the use of this file, please contact ** Nokia at qt-info@nokia.com. diff --git a/src/gui/text/qabstractfontengine_qws.h b/src/gui/text/qabstractfontengine_qws.h index 4f00b3c..0c1e18e 100644 --- a/src/gui/text/qabstractfontengine_qws.h +++ b/src/gui/text/qabstractfontengine_qws.h @@ -1,7 +1,6 @@ /**************************************************************************** ** ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** ** This file is part of the QtGui module of the Qt Toolkit. @@ -21,9 +20,10 @@ ** ensure the GNU Lesser General Public License version 2.1 requirements ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. ** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.1, included in the file LGPL_EXCEPTION.txt in this +** package. ** ** If you have questions regarding the use of this file, please contact ** Nokia at qt-info@nokia.com. diff --git a/src/gui/text/qabstracttextdocumentlayout.cpp b/src/gui/text/qabstracttextdocumentlayout.cpp index ab0a64c..1ea5feb 100644 --- a/src/gui/text/qabstracttextdocumentlayout.cpp +++ b/src/gui/text/qabstracttextdocumentlayout.cpp @@ -1,7 +1,6 @@ /**************************************************************************** ** ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** ** This file is part of the QtGui module of the Qt Toolkit. @@ -21,9 +20,10 @@ ** ensure the GNU Lesser General Public License version 2.1 requirements ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. ** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.1, included in the file LGPL_EXCEPTION.txt in this +** package. ** ** If you have questions regarding the use of this file, please contact ** Nokia at qt-info@nokia.com. @@ -55,7 +55,7 @@ QT_BEGIN_NAMESPACE \brief The QAbstractTextDocumentLayout class is an abstract base class used to implement custom layouts for QTextDocuments. - \ingroup text + \ingroup richtext-processing The standard layout provided by Qt can handle simple word processing including inline images, lists and tables. @@ -79,6 +79,7 @@ QT_BEGIN_NAMESPACE \class QTextObjectInterface \brief The QTextObjectInterface class allows drawing of custom text objects in \l{QTextDocument}s. + \since 4.5 A text object describes the structure of one or more elements in a text document; for instance, images imported from HTML are diff --git a/src/gui/text/qabstracttextdocumentlayout.h b/src/gui/text/qabstracttextdocumentlayout.h index 2f8a746..fab7590 100644 --- a/src/gui/text/qabstracttextdocumentlayout.h +++ b/src/gui/text/qabstracttextdocumentlayout.h @@ -1,7 +1,6 @@ /**************************************************************************** ** ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** ** This file is part of the QtGui module of the Qt Toolkit. @@ -21,9 +20,10 @@ ** ensure the GNU Lesser General Public License version 2.1 requirements ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. ** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.1, included in the file LGPL_EXCEPTION.txt in this +** package. ** ** If you have questions regarding the use of this file, please contact ** Nokia at qt-info@nokia.com. diff --git a/src/gui/text/qabstracttextdocumentlayout_p.h b/src/gui/text/qabstracttextdocumentlayout_p.h index 4e1ccd4..f54b521 100644 --- a/src/gui/text/qabstracttextdocumentlayout_p.h +++ b/src/gui/text/qabstracttextdocumentlayout_p.h @@ -1,7 +1,6 @@ /**************************************************************************** ** ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** ** This file is part of the QtGui module of the Qt Toolkit. @@ -21,9 +20,10 @@ ** ensure the GNU Lesser General Public License version 2.1 requirements ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. ** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.1, included in the file LGPL_EXCEPTION.txt in this +** package. ** ** If you have questions regarding the use of this file, please contact ** Nokia at qt-info@nokia.com. diff --git a/src/gui/text/qcssparser.cpp b/src/gui/text/qcssparser.cpp index 34cb074..a38f276 100644 --- a/src/gui/text/qcssparser.cpp +++ b/src/gui/text/qcssparser.cpp @@ -1,7 +1,6 @@ /**************************************************************************** ** ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** ** This file is part of the QtGui module of the Qt Toolkit. @@ -21,9 +20,10 @@ ** ensure the GNU Lesser General Public License version 2.1 requirements ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. ** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.1, included in the file LGPL_EXCEPTION.txt in this +** package. ** ** If you have questions regarding the use of this file, please contact ** Nokia at qt-info@nokia.com. @@ -48,6 +48,7 @@ #include <qfontmetrics.h> #include <qbrush.h> #include <qimagereader.h> +#include "private/qfunctions_p.h" #ifndef QT_NO_CSSPARSER @@ -57,46 +58,6 @@ QT_BEGIN_NAMESPACE using namespace QCss; -const char *Scanner::tokenName(QCss::TokenType t) -{ - switch (t) { - case NONE: return "NONE"; - case S: return "S"; - case CDO: return "CDO"; - case CDC: return "CDC"; - case INCLUDES: return "INCLUDES"; - case DASHMATCH: return "DASHMATCH"; - case LBRACE: return "LBRACE"; - case PLUS: return "PLUS"; - case GREATER: return "GREATER"; - case COMMA: return "COMMA"; - case STRING: return "STRING"; - case INVALID: return "INVALID"; - case IDENT: return "IDENT"; - case HASH: return "HASH"; - case ATKEYWORD_SYM: return "ATKEYWORD_SYM"; - case EXCLAMATION_SYM: return "EXCLAMATION_SYM"; - case LENGTH: return "LENGTH"; - case PERCENTAGE: return "PERCENTAGE"; - case NUMBER: return "NUMBER"; - case FUNCTION: return "FUNCTION"; - case COLON: return "COLON"; - case SEMICOLON: return "SEMICOLON"; - case RBRACE: return "RBRACE"; - case SLASH: return "SLASH"; - case MINUS: return "MINUS"; - case DOT: return "DOT"; - case STAR: return "STAR"; - case LBRACKET: return "LBRACKET"; - case RBRACKET: return "RBRACKET"; - case EQUAL: return "EQUAL"; - case LPAREN: return "LPAREN"; - case RPAREN: return "RPAREN"; - case OR: return "OR"; - } - return ""; -} - struct QCssKnownValue { const char *name; @@ -239,6 +200,7 @@ static const QCssKnownValue values[NumKnownValues - 1] = { { "link", Value_Link }, { "link-visited", Value_LinkVisited }, { "lower-alpha", Value_LowerAlpha }, + { "lower-roman", Value_LowerRoman }, { "lowercase", Value_Lowercase }, { "medium", Value_Medium }, { "mid", Value_Mid }, @@ -270,6 +232,7 @@ static const QCssKnownValue values[NumKnownValues - 1] = { { "transparent", Value_Transparent }, { "underline", Value_Underline }, { "upper-alpha", Value_UpperAlpha }, + { "upper-roman", Value_UpperRoman }, { "uppercase", Value_Uppercase }, { "wave", Value_Wave }, { "window", Value_Window }, @@ -279,10 +242,10 @@ static const QCssKnownValue values[NumKnownValues - 1] = { }; //Map id to strings as they appears in the 'values' array above -static const int indexOfId[NumKnownValues] = { 0, 40, 47, 41, 48, 53, 34, 26, 68, 69, 25, 42, 5, 62, 46, - 29, 57, 58, 27, 50, 60, 6, 10, 38, 55, 19, 13, 17, 18, 20, 21, 49, 24, 45, 65, 36, 3, 2, 39, 61, 16, - 11, 56, 14, 32, 63, 54, 64, 33, 67, 8, 28, 37, 12, 35, 59, 7, 9, 4, 66, 52, 22, 23, 30, 31, 1, 15, 0, - 51, 44, 43 }; +static const short indexOfId[NumKnownValues] = { 0, 41, 48, 42, 49, 54, 35, 26, 70, 71, 25, 43, 5, 63, 47, + 29, 58, 59, 27, 51, 61, 6, 10, 39, 56, 19, 13, 17, 18, 20, 21, 50, 24, 46, 67, 37, 3, 2, 40, 62, 16, + 11, 57, 14, 32, 64, 33, 65, 55, 66, 34, 69, 8, 28, 38, 12, 36, 60, 7, 9, 4, 68, 53, 22, 23, 30, 31, + 1, 15, 0, 52, 45, 44 }; QString Value::toString() const { @@ -378,12 +341,12 @@ static const QCssKnownValue styleFeatures[NumKnownStyleFeatures - 1] = { { "none", StyleFeature_None } }; -static bool operator<(const QString &name, const QCssKnownValue &prop) +Q_STATIC_GLOBAL_OPERATOR bool operator<(const QString &name, const QCssKnownValue &prop) { return QString::compare(name, QLatin1String(prop.name), Qt::CaseInsensitive) < 0; } -static bool operator<(const QCssKnownValue &prop, const QString &name) +Q_STATIC_GLOBAL_OPERATOR bool operator<(const QCssKnownValue &prop, const QString &name) { return QString::compare(QLatin1String(prop.name), name, Qt::CaseInsensitive) < 0; } @@ -420,10 +383,7 @@ LengthData ValueExtractor::lengthValue(const Value& v) if (data.unit != LengthData::None) s.chop(2); - bool ok; - data.number = s.toDouble(&ok); - if (!ok) - data.number = 0; + data.number = s.toDouble(); return data; } @@ -749,7 +709,7 @@ static ColorData parseColorValue(Value v) for (int i = 0; i < qMin(colorDigits.count(), 7); i += 2) { if (colorDigits.at(i).type == Value::Percentage) { - colorDigits[i].variant = colorDigits.at(i).variant.toDouble() * 255. / 100.; + colorDigits[i].variant = colorDigits.at(i).variant.toReal() * (255. / 100.); colorDigits[i].type = Value::Number; } else if (colorDigits.at(i).type != Value::Number) { return ColorData(); @@ -826,19 +786,19 @@ static BrushData parseBrushValue(const Value &v, const QPalette &pal) ColorData cd = parseColorValue(color); if(cd.type == ColorData::Role) dependsOnThePalette = true; - stops.append(QGradientStop(stop.variant.toDouble(), colorFromData(cd, pal))); + stops.append(QGradientStop(stop.variant.toReal(), colorFromData(cd, pal))); } else { parser.next(); Value value; - parser.parseTerm(&value); + (void)parser.parseTerm(&value); if (attr.compare(QLatin1String("spread"), Qt::CaseInsensitive) == 0) { spread = spreads.indexOf(value.variant.toString()); } else { - vars[attr] = value.variant.toString().toDouble(); + vars[attr] = value.variant.toReal(); } } parser.skipSpace(); - parser.test(COMMA); + (void)parser.test(COMMA); } if (gradType == 0) { @@ -1117,8 +1077,8 @@ static bool setFontSizeFromValue(Value value, QFont *font, int *fontSizeAdjustme if (s.endsWith(QLatin1String("pt"), Qt::CaseInsensitive)) { s.chop(2); value.variant = s; - if (value.variant.convert(QVariant::Double)) { - font->setPointSizeF(value.variant.toDouble()); + if (value.variant.convert((QVariant::Type)qMetaTypeId<qreal>())) { + font->setPointSizeF(value.variant.toReal()); valid = true; } } else if (s.endsWith(QLatin1String("px"), Qt::CaseInsensitive)) { @@ -1211,7 +1171,7 @@ static void parseShorthandFontProperty(const QVector<Value> &values, QFont *font { font->setStyle(QFont::StyleNormal); font->setWeight(QFont::Normal); - *fontSizeAdjustment = 0; + *fontSizeAdjustment = -255; int i = 0; while (i < values.count()) { @@ -1508,7 +1468,7 @@ QRect Declaration::rectValue() const QStringList func = v.variant.toStringList(); if (func.count() != 2 || func.at(0).compare(QLatin1String("rect")) != 0) return QRect(); - QStringList args = func[1].split(QLatin1String(" "), QString::SkipEmptyParts); + QStringList args = func[1].split(QLatin1Char(' '), QString::SkipEmptyParts); if (args.count() != 4) return QRect(); QRect rect(args[0].toInt(), args[1].toInt(), args[2].toInt(), args[3].toInt()); @@ -2153,7 +2113,7 @@ void Parser::init(const QString &css, bool isFile) if (isFile) { QFile file(css); if (file.open(QFile::ReadOnly)) { - sourcePath = QFileInfo(styleSheet).absolutePath() + QLatin1String("/"); + sourcePath = QFileInfo(styleSheet).absolutePath() + QLatin1Char('/'); QTextStream stream(&file); styleSheet = stream.readAll(); } else { @@ -2166,6 +2126,7 @@ void Parser::init(const QString &css, bool isFile) hasEscapeSequences = false; symbols.resize(0); + symbols.reserve(8); Scanner::scan(Scanner::preprocess(styleSheet, &hasEscapeSequences), &symbols); index = 0; errorIndex = -1; @@ -2499,7 +2460,7 @@ bool Parser::parseAttrib(AttributeSelector *attr) bool Parser::parsePseudo(Pseudo *pseudo) { - test(COLON); + (void)test(COLON); pseudo->negated = test(EXCLAMATION_SYM); if (test(IDENT)) { pseudo->name = lexem(); diff --git a/src/gui/text/qcssparser_p.h b/src/gui/text/qcssparser_p.h index 72a9982..8f30013 100644 --- a/src/gui/text/qcssparser_p.h +++ b/src/gui/text/qcssparser_p.h @@ -1,7 +1,6 @@ /**************************************************************************** ** ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** ** This file is part of the QtGui module of the Qt Toolkit. @@ -21,9 +20,10 @@ ** ensure the GNU Lesser General Public License version 2.1 requirements ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. ** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.1, included in the file LGPL_EXCEPTION.txt in this +** package. ** ** If you have questions regarding the use of this file, please contact ** Nokia at qt-info@nokia.com. @@ -67,6 +67,11 @@ #ifndef QT_NO_CSSPARSER +// VxWorks defines NONE as (-1) "for times when NULL won't do" +#if defined(Q_OS_VXWORKS) && defined(NONE) +# undef NONE +#endif + QT_BEGIN_NAMESPACE namespace QCss @@ -223,6 +228,8 @@ enum KnownValue { Value_Decimal, Value_LowerAlpha, Value_UpperAlpha, + Value_LowerRoman, + Value_UpperRoman, Value_SmallCaps, Value_Uppercase, Value_Lowercase, @@ -361,18 +368,18 @@ struct Q_GUI_EXPORT Value }; struct ColorData { - ColorData() : type(Invalid) {} - ColorData(const QColor &col) : color(col) , type(Color) {} - ColorData(QPalette::ColorRole r) : role(r) , type(Role) {} + ColorData() : role(QPalette::NoRole), type(Invalid) {} + ColorData(const QColor &col) : color(col), role(QPalette::NoRole), type(Color) {} + ColorData(QPalette::ColorRole r) : role(r), type(Role) {} QColor color; QPalette::ColorRole role; enum { Invalid, Color, Role} type; }; struct BrushData { - BrushData() : type(Invalid) {} - BrushData(const QBrush &br) : brush(br) , type(Brush) {} - BrushData(QPalette::ColorRole r) : role(r) , type(Role) {} + BrushData() : role(QPalette::NoRole), type(Invalid) {} + BrushData(const QBrush &br) : brush(br), role(QPalette::NoRole), type(Brush) {} + BrushData(QPalette::ColorRole r) : role(r), type(Role) {} QBrush brush; QPalette::ColorRole role; enum { Invalid, Brush, Role, DependsOnThePalette } type; @@ -403,7 +410,7 @@ struct BorderData { // 4. QVector<Declaration> - { prop1: value1; prop2: value2; } // 5. Declaration - prop1: value1; -struct Q_GUI_EXPORT Declaration +struct Q_AUTOTEST_EXPORT Declaration { struct DeclarationData : public QSharedData { @@ -495,16 +502,16 @@ const quint64 PseudoClass_Alternate = Q_UINT64_C(0x0000100000000000); const quint64 PseudoClass_Any = Q_UINT64_C(0x0000ffffffffffff); const int NumPseudos = 46; -struct Q_GUI_EXPORT Pseudo +struct Pseudo { - Pseudo() : negated(false) { } + Pseudo() : type(0), negated(false) { } quint64 type; QString name; QString function; bool negated; }; -struct Q_GUI_EXPORT AttributeSelector +struct AttributeSelector { enum ValueMatchType { NoMatch, @@ -519,7 +526,7 @@ struct Q_GUI_EXPORT AttributeSelector ValueMatchType valueMatchCriterium; }; -struct Q_GUI_EXPORT BasicSelector +struct BasicSelector { inline BasicSelector() : relationToNext(NoRelation) {} @@ -539,7 +546,7 @@ struct Q_GUI_EXPORT BasicSelector Relation relationToNext; }; -struct Q_GUI_EXPORT Selector +struct Q_AUTOTEST_EXPORT Selector { QVector<BasicSelector> basicSelectors; int specificity() const; @@ -552,7 +559,7 @@ struct MediaRule; struct PageRule; struct ImportRule; -struct Q_GUI_EXPORT ValueExtractor +struct Q_AUTOTEST_EXPORT ValueExtractor { ValueExtractor(const QVector<Declaration> &declarations, const QPalette & = QPalette()); @@ -586,7 +593,7 @@ private: QPalette pal; }; -struct Q_GUI_EXPORT StyleRule +struct StyleRule { StyleRule() : order(0) { } QVector<Selector> selectors; @@ -594,19 +601,19 @@ struct Q_GUI_EXPORT StyleRule int order; }; -struct Q_GUI_EXPORT MediaRule +struct MediaRule { QStringList media; QVector<StyleRule> styleRules; }; -struct Q_GUI_EXPORT PageRule +struct PageRule { QString selector; QVector<Declaration> declarations; }; -struct Q_GUI_EXPORT ImportRule +struct ImportRule { QString href; QStringList media; @@ -620,7 +627,7 @@ enum StyleSheetOrigin { StyleSheetOrigin_Inline }; -struct Q_GUI_EXPORT StyleSheet +struct StyleSheet { StyleSheet() : origin(StyleSheetOrigin_Unspecified), depth(0) { } QVector<StyleRule> styleRules; //only contains rules that are not indexed @@ -719,7 +726,7 @@ enum TokenType { struct Q_GUI_EXPORT Symbol { - inline Symbol() : start(0), len(-1) {} + inline Symbol() : token(NONE), start(0), len(-1) {} TokenType token; QString text; int start, len; @@ -731,7 +738,6 @@ class Q_AUTOTEST_EXPORT Scanner public: static QString preprocess(const QString &input, bool *hasEscapeSequences = 0); static void scan(const QString &preprocessedInput, QVector<Symbol> *symbols); - static const char *tokenName(TokenType t); }; class Q_GUI_EXPORT Parser diff --git a/src/gui/text/qcssscanner.cpp b/src/gui/text/qcssscanner.cpp index c1a739b..5bbf638 100644 --- a/src/gui/text/qcssscanner.cpp +++ b/src/gui/text/qcssscanner.cpp @@ -1,7 +1,6 @@ /**************************************************************************** ** ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** ** This file is part of the QtGui module of the Qt Toolkit. @@ -21,9 +20,10 @@ ** ensure the GNU Lesser General Public License version 2.1 requirements ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. ** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.1, included in the file LGPL_EXCEPTION.txt in this +** package. ** ** If you have questions regarding the use of this file, please contact ** Nokia at qt-info@nokia.com. @@ -46,7 +46,7 @@ public: QCssScanner_Generated(const QString &inp); inline QChar next() { - return (pos < input.length()) ? input.at(pos++).toLower() : QChar(); + return (pos < input.length()) ? input.at(pos++) : QChar(); } int handleCommentStart(); int lex(); @@ -73,7 +73,7 @@ int QCssScanner_Generated::lex() int lastAcceptingPos = -1; int token = -1; QChar ch; - + // initial state ch = next(); if (ch.unicode() >= 9 && ch.unicode() <= 10) @@ -146,7 +146,7 @@ int QCssScanner_Generated::lex() } if (ch.unicode() == 95) goto state_24; - if ((ch.unicode() >= 'a' && ch.unicode() <= 'z') || ch.unicode() >= 256) + if ((ch.unicode() >= 'a' && ch.unicode() <= 'z') || (ch.unicode() >= 'A' && ch.unicode() <= 'Z') || ch.unicode() >= 256) goto state_24; if (ch.unicode() == 123) goto state_25; @@ -196,7 +196,7 @@ int QCssScanner_Generated::lex() goto state_32; if (ch.unicode() >= 93 && ch.unicode() <= 96) goto state_30; - if ((ch.unicode() >= 'a' && ch.unicode() <= 'z') || ch.unicode() >= 256) + if ((ch.unicode() >= 'a' && ch.unicode() <= 'z') || (ch.unicode() >= 'A' && ch.unicode() <= 'Z') || ch.unicode() >= 256) goto state_30; if (ch.unicode() >= 123) goto state_30; @@ -211,7 +211,7 @@ int QCssScanner_Generated::lex() goto state_34; if (ch.unicode() == 95) goto state_33; - if ((ch.unicode() >= 'a' && ch.unicode() <= 'z') || ch.unicode() >= 256) + if ((ch.unicode() >= 'a' && ch.unicode() <= 'z') || (ch.unicode() >= 'A' && ch.unicode() <= 'Z') || ch.unicode() >= 256) goto state_33; goto out; state_5: @@ -232,7 +232,7 @@ int QCssScanner_Generated::lex() goto state_37; if (ch.unicode() >= 93 && ch.unicode() <= 96) goto state_35; - if ((ch.unicode() >= 'a' && ch.unicode() <= 'z') || ch.unicode() >= 256) + if ((ch.unicode() >= 'a' && ch.unicode() <= 'z') || (ch.unicode() >= 'A' && ch.unicode() <= 'Z') || ch.unicode() >= 256) goto state_35; if (ch.unicode() >= 123) goto state_35; @@ -255,7 +255,7 @@ int QCssScanner_Generated::lex() goto state_22; if (ch.unicode() == 95) goto state_24; - if ((ch.unicode() >= 'a' && ch.unicode() <= 'z') || ch.unicode() >= 256) + if ((ch.unicode() >= 'a' && ch.unicode() <= 'z') || (ch.unicode() >= 'A' && ch.unicode() <= 'Z') || ch.unicode() >= 256) goto state_24; goto out; state_12: @@ -290,7 +290,7 @@ int QCssScanner_Generated::lex() goto state_45; if (ch.unicode() == 95) goto state_46; - if ((ch.unicode() >= 'a' && ch.unicode() <= 'z') || ch.unicode() >= 256) + if ((ch.unicode() >= 'a' && ch.unicode() <= 'z') || (ch.unicode() >= 'A' && ch.unicode() <= 'Z') || ch.unicode() >= 256) goto state_46; goto out; state_17: @@ -310,7 +310,7 @@ int QCssScanner_Generated::lex() goto state_49; if (ch.unicode() == 95) goto state_50; - if ((ch.unicode() >= 'a' && ch.unicode() <= 'z') || ch.unicode() >= 256) + if ((ch.unicode() >= 'a' && ch.unicode() <= 'z') || (ch.unicode() >= 'A' && ch.unicode() <= 'Z') || ch.unicode() >= 256) goto state_50; goto out; state_22: @@ -340,7 +340,7 @@ int QCssScanner_Generated::lex() goto state_54; if (ch.unicode() == 95) goto state_53; - if ((ch.unicode() >= 'a' && ch.unicode() <= 'z') || ch.unicode() >= 256) + if ((ch.unicode() >= 'a' && ch.unicode() <= 'z') || (ch.unicode() >= 'A' && ch.unicode() <= 'Z') || ch.unicode() >= 256) goto state_53; goto out; state_25: @@ -400,7 +400,7 @@ int QCssScanner_Generated::lex() goto state_32; if (ch.unicode() >= 93 && ch.unicode() <= 96) goto state_30; - if ((ch.unicode() >= 'a' && ch.unicode() <= 'z') || ch.unicode() >= 256) + if ((ch.unicode() >= 'a' && ch.unicode() <= 'z') || (ch.unicode() >= 'A' && ch.unicode() <= 'Z') || ch.unicode() >= 256) goto state_30; if (ch.unicode() >= 123) goto state_30; @@ -440,7 +440,7 @@ int QCssScanner_Generated::lex() goto state_62; if (ch.unicode() == 95) goto state_61; - if ((ch.unicode() >= 'a' && ch.unicode() <= 'z') || ch.unicode() >= 256) + if ((ch.unicode() >= 'a' && ch.unicode() <= 'z') || (ch.unicode() >= 'A' && ch.unicode() <= 'Z') || ch.unicode() >= 256) goto state_61; goto out; state_34: @@ -474,7 +474,7 @@ int QCssScanner_Generated::lex() goto state_37; if (ch.unicode() >= 93 && ch.unicode() <= 96) goto state_35; - if ((ch.unicode() >= 'a' && ch.unicode() <= 'z') || ch.unicode() >= 256) + if ((ch.unicode() >= 'a' && ch.unicode() <= 'z') || (ch.unicode() >= 'A' && ch.unicode() <= 'Z') || ch.unicode() >= 256) goto state_35; if (ch.unicode() >= 123) goto state_35; @@ -523,7 +523,7 @@ int QCssScanner_Generated::lex() goto state_45; if (ch.unicode() == 95) goto state_46; - if ((ch.unicode() >= 'a' && ch.unicode() <= 'z') || ch.unicode() >= 256) + if ((ch.unicode() >= 'a' && ch.unicode() <= 'z') || (ch.unicode() >= 'A' && ch.unicode() <= 'Z') || ch.unicode() >= 256) goto state_46; goto out; state_41: @@ -536,7 +536,7 @@ int QCssScanner_Generated::lex() goto state_45; if (ch.unicode() == 95) goto state_46; - if ((ch.unicode() >= 'a' && ch.unicode() <= 'z') || ch.unicode() >= 256) + if ((ch.unicode() >= 'a' && ch.unicode() <= 'z') || (ch.unicode() >= 'A' && ch.unicode() <= 'Z') || ch.unicode() >= 256) goto state_46; goto out; state_43: @@ -560,7 +560,7 @@ int QCssScanner_Generated::lex() goto state_45; if (ch.unicode() == 95) goto state_46; - if ((ch.unicode() >= 'a' && ch.unicode() <= 'z') || ch.unicode() >= 256) + if ((ch.unicode() >= 'a' && ch.unicode() <= 'z') || (ch.unicode() >= 'A' && ch.unicode() <= 'Z') || ch.unicode() >= 256) goto state_46; goto out; state_45: @@ -588,7 +588,7 @@ int QCssScanner_Generated::lex() goto state_72; if (ch.unicode() == 95) goto state_71; - if ((ch.unicode() >= 'a' && ch.unicode() <= 'z') || ch.unicode() >= 256) + if ((ch.unicode() >= 'a' && ch.unicode() <= 'z') || (ch.unicode() >= 'A' && ch.unicode() <= 'Z') || ch.unicode() >= 256) goto state_71; goto out; state_47: @@ -602,7 +602,7 @@ int QCssScanner_Generated::lex() goto state_49; if (ch.unicode() == 95) goto state_50; - if ((ch.unicode() >= 'a' && ch.unicode() <= 'z') || ch.unicode() >= 256) + if ((ch.unicode() >= 'a' && ch.unicode() <= 'z') || (ch.unicode() >= 'A' && ch.unicode() <= 'Z') || ch.unicode() >= 256) goto state_50; goto out; state_49: @@ -630,7 +630,7 @@ int QCssScanner_Generated::lex() goto state_76; if (ch.unicode() == 95) goto state_75; - if ((ch.unicode() >= 'a' && ch.unicode() <= 'z') || ch.unicode() >= 256) + if ((ch.unicode() >= 'a' && ch.unicode() <= 'z') || (ch.unicode() >= 'A' && ch.unicode() <= 'Z') || ch.unicode() >= 256) goto state_75; goto out; state_51: @@ -647,7 +647,7 @@ int QCssScanner_Generated::lex() goto state_54; if (ch.unicode() == 95) goto state_53; - if ((ch.unicode() >= 'a' && ch.unicode() <= 'z') || ch.unicode() >= 256) + if ((ch.unicode() >= 'a' && ch.unicode() <= 'z') || (ch.unicode() >= 'A' && ch.unicode() <= 'Z') || ch.unicode() >= 256) goto state_53; goto out; state_52: @@ -668,7 +668,7 @@ int QCssScanner_Generated::lex() goto state_54; if (ch.unicode() == 95) goto state_53; - if ((ch.unicode() >= 'a' && ch.unicode() <= 'z') || ch.unicode() >= 256) + if ((ch.unicode() >= 'a' && ch.unicode() <= 'z') || (ch.unicode() >= 'A' && ch.unicode() <= 'Z') || ch.unicode() >= 256) goto state_53; goto out; state_54: @@ -702,7 +702,7 @@ int QCssScanner_Generated::lex() goto state_32; if (ch.unicode() >= 93 && ch.unicode() <= 96) goto state_30; - if ((ch.unicode() >= 'a' && ch.unicode() <= 'z') || ch.unicode() >= 256) + if ((ch.unicode() >= 'a' && ch.unicode() <= 'z') || (ch.unicode() >= 'A' && ch.unicode() <= 'Z') || ch.unicode() >= 256) goto state_30; if (ch.unicode() >= 123) goto state_30; @@ -725,7 +725,7 @@ int QCssScanner_Generated::lex() goto state_32; if (ch.unicode() >= 93 && ch.unicode() <= 96) goto state_30; - if ((ch.unicode() >= 'a' && ch.unicode() <= 'z') || ch.unicode() >= 256) + if ((ch.unicode() >= 'a' && ch.unicode() <= 'z') || (ch.unicode() >= 'A' && ch.unicode() <= 'Z') || ch.unicode() >= 256) goto state_30; if (ch.unicode() >= 123) goto state_30; @@ -748,7 +748,7 @@ int QCssScanner_Generated::lex() goto state_32; if (ch.unicode() >= 93 && ch.unicode() <= 96) goto state_30; - if ((ch.unicode() >= 'a' && ch.unicode() <= 'z') || ch.unicode() >= 256) + if ((ch.unicode() >= 'a' && ch.unicode() <= 'z') || (ch.unicode() >= 'A' && ch.unicode() <= 'Z') || ch.unicode() >= 256) goto state_30; if (ch.unicode() >= 123) goto state_30; @@ -773,7 +773,7 @@ int QCssScanner_Generated::lex() goto state_32; if (ch.unicode() >= 93 && ch.unicode() <= 96) goto state_30; - if ((ch.unicode() >= 'a' && ch.unicode() <= 'z') || ch.unicode() >= 256) + if ((ch.unicode() >= 'a' && ch.unicode() <= 'z') || (ch.unicode() >= 'A' && ch.unicode() <= 'Z') || ch.unicode() >= 256) goto state_30; if (ch.unicode() >= 123) goto state_30; @@ -790,7 +790,7 @@ int QCssScanner_Generated::lex() goto state_62; if (ch.unicode() == 95) goto state_61; - if ((ch.unicode() >= 'a' && ch.unicode() <= 'z') || ch.unicode() >= 256) + if ((ch.unicode() >= 'a' && ch.unicode() <= 'z') || (ch.unicode() >= 'A' && ch.unicode() <= 'Z') || ch.unicode() >= 256) goto state_61; goto out; state_62: @@ -818,7 +818,7 @@ int QCssScanner_Generated::lex() goto state_62; if (ch.unicode() == 95) goto state_61; - if ((ch.unicode() >= 'a' && ch.unicode() <= 'z') || ch.unicode() >= 256) + if ((ch.unicode() >= 'a' && ch.unicode() <= 'z') || (ch.unicode() >= 'A' && ch.unicode() <= 'Z') || ch.unicode() >= 256) goto state_61; goto out; state_64: @@ -839,7 +839,7 @@ int QCssScanner_Generated::lex() goto state_37; if (ch.unicode() >= 93 && ch.unicode() <= 96) goto state_35; - if ((ch.unicode() >= 'a' && ch.unicode() <= 'z') || ch.unicode() >= 256) + if ((ch.unicode() >= 'a' && ch.unicode() <= 'z') || (ch.unicode() >= 'A' && ch.unicode() <= 'Z') || ch.unicode() >= 256) goto state_35; if (ch.unicode() >= 123) goto state_35; @@ -862,7 +862,7 @@ int QCssScanner_Generated::lex() goto state_37; if (ch.unicode() >= 93 && ch.unicode() <= 96) goto state_35; - if ((ch.unicode() >= 'a' && ch.unicode() <= 'z') || ch.unicode() >= 256) + if ((ch.unicode() >= 'a' && ch.unicode() <= 'z') || (ch.unicode() >= 'A' && ch.unicode() <= 'Z') || ch.unicode() >= 256) goto state_35; if (ch.unicode() >= 123) goto state_35; @@ -885,7 +885,7 @@ int QCssScanner_Generated::lex() goto state_37; if (ch.unicode() >= 93 && ch.unicode() <= 96) goto state_35; - if ((ch.unicode() >= 'a' && ch.unicode() <= 'z') || ch.unicode() >= 256) + if ((ch.unicode() >= 'a' && ch.unicode() <= 'z') || (ch.unicode() >= 'A' && ch.unicode() <= 'Z') || ch.unicode() >= 256) goto state_35; if (ch.unicode() >= 123) goto state_35; @@ -910,7 +910,7 @@ int QCssScanner_Generated::lex() goto state_37; if (ch.unicode() >= 93 && ch.unicode() <= 96) goto state_35; - if ((ch.unicode() >= 'a' && ch.unicode() <= 'z') || ch.unicode() >= 256) + if ((ch.unicode() >= 'a' && ch.unicode() <= 'z') || (ch.unicode() >= 'A' && ch.unicode() <= 'Z') || ch.unicode() >= 256) goto state_35; if (ch.unicode() >= 123) goto state_35; @@ -929,7 +929,7 @@ int QCssScanner_Generated::lex() goto state_45; if (ch.unicode() == 95) goto state_46; - if ((ch.unicode() >= 'a' && ch.unicode() <= 'z') || ch.unicode() >= 256) + if ((ch.unicode() >= 'a' && ch.unicode() <= 'z') || (ch.unicode() >= 'A' && ch.unicode() <= 'Z') || ch.unicode() >= 256) goto state_46; goto out; state_70: @@ -944,7 +944,7 @@ int QCssScanner_Generated::lex() goto state_72; if (ch.unicode() == 95) goto state_71; - if ((ch.unicode() >= 'a' && ch.unicode() <= 'z') || ch.unicode() >= 256) + if ((ch.unicode() >= 'a' && ch.unicode() <= 'z') || (ch.unicode() >= 'A' && ch.unicode() <= 'Z') || ch.unicode() >= 256) goto state_71; goto out; state_71: @@ -959,7 +959,7 @@ int QCssScanner_Generated::lex() goto state_72; if (ch.unicode() == 95) goto state_71; - if ((ch.unicode() >= 'a' && ch.unicode() <= 'z') || ch.unicode() >= 256) + if ((ch.unicode() >= 'a' && ch.unicode() <= 'z') || (ch.unicode() >= 'A' && ch.unicode() <= 'Z') || ch.unicode() >= 256) goto state_71; goto out; state_72: @@ -994,7 +994,7 @@ int QCssScanner_Generated::lex() goto state_76; if (ch.unicode() == 95) goto state_75; - if ((ch.unicode() >= 'a' && ch.unicode() <= 'z') || ch.unicode() >= 256) + if ((ch.unicode() >= 'a' && ch.unicode() <= 'z') || (ch.unicode() >= 'A' && ch.unicode() <= 'Z') || ch.unicode() >= 256) goto state_75; goto out; state_75: @@ -1009,7 +1009,7 @@ int QCssScanner_Generated::lex() goto state_76; if (ch.unicode() == 95) goto state_75; - if ((ch.unicode() >= 'a' && ch.unicode() <= 'z') || ch.unicode() >= 256) + if ((ch.unicode() >= 'a' && ch.unicode() <= 'z') || (ch.unicode() >= 'A' && ch.unicode() <= 'Z') || ch.unicode() >= 256) goto state_75; goto out; state_76: @@ -1039,7 +1039,7 @@ int QCssScanner_Generated::lex() goto state_54; if (ch.unicode() == 95) goto state_53; - if ((ch.unicode() >= 'a' && ch.unicode() <= 'z') || ch.unicode() >= 256) + if ((ch.unicode() >= 'a' && ch.unicode() <= 'z') || (ch.unicode() >= 'A' && ch.unicode() <= 'Z') || ch.unicode() >= 256) goto state_53; goto out; state_78: @@ -1060,7 +1060,7 @@ int QCssScanner_Generated::lex() goto state_32; if (ch.unicode() >= 93 && ch.unicode() <= 96) goto state_30; - if ((ch.unicode() >= 'a' && ch.unicode() <= 'z') || ch.unicode() >= 256) + if ((ch.unicode() >= 'a' && ch.unicode() <= 'z') || (ch.unicode() >= 'A' && ch.unicode() <= 'Z') || ch.unicode() >= 256) goto state_30; if (ch.unicode() >= 123) goto state_30; @@ -1077,7 +1077,7 @@ int QCssScanner_Generated::lex() goto state_62; if (ch.unicode() == 95) goto state_61; - if ((ch.unicode() >= 'a' && ch.unicode() <= 'z') || ch.unicode() >= 256) + if ((ch.unicode() >= 'a' && ch.unicode() <= 'z') || (ch.unicode() >= 'A' && ch.unicode() <= 'Z') || ch.unicode() >= 256) goto state_61; goto out; state_80: @@ -1098,7 +1098,7 @@ int QCssScanner_Generated::lex() goto state_37; if (ch.unicode() >= 93 && ch.unicode() <= 96) goto state_35; - if ((ch.unicode() >= 'a' && ch.unicode() <= 'z') || ch.unicode() >= 256) + if ((ch.unicode() >= 'a' && ch.unicode() <= 'z') || (ch.unicode() >= 'A' && ch.unicode() <= 'Z') || ch.unicode() >= 256) goto state_35; if (ch.unicode() >= 123) goto state_35; @@ -1115,7 +1115,7 @@ int QCssScanner_Generated::lex() goto state_72; if (ch.unicode() == 95) goto state_71; - if ((ch.unicode() >= 'a' && ch.unicode() <= 'z') || ch.unicode() >= 256) + if ((ch.unicode() >= 'a' && ch.unicode() <= 'z') || (ch.unicode() >= 'A' && ch.unicode() <= 'Z') || ch.unicode() >= 256) goto state_71; goto out; state_83: @@ -1130,12 +1130,12 @@ int QCssScanner_Generated::lex() goto state_76; if (ch.unicode() == 95) goto state_75; - if ((ch.unicode() >= 'a' && ch.unicode() <= 'z') || ch.unicode() >= 256) + if ((ch.unicode() >= 'a' && ch.unicode() <= 'z') || (ch.unicode() >= 'A' && ch.unicode() <= 'Z') || ch.unicode() >= 256) goto state_75; goto out; found: lastAcceptingPos = pos; - + out: if (lastAcceptingPos != -1) { lexemLength = lastAcceptingPos - lexemStart; diff --git a/src/gui/text/qfont.cpp b/src/gui/text/qfont.cpp index 7e820c4..03f69db 100644 --- a/src/gui/text/qfont.cpp +++ b/src/gui/text/qfont.cpp @@ -1,7 +1,6 @@ /**************************************************************************** ** ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** ** This file is part of the QtGui module of the Qt Toolkit. @@ -21,9 +20,10 @@ ** ensure the GNU Lesser General Public License version 2.1 requirements ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. ** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.1, included in the file LGPL_EXCEPTION.txt in this +** package. ** ** If you have questions regarding the use of this file, please contact ** Nokia at qt-info@nokia.com. @@ -72,6 +72,9 @@ #include "qfontengine_qpf_p.h" #endif #endif +#ifdef Q_OS_SYMBIAN +#include "qt_s60_p.h" +#endif #include <QMutexLocker> @@ -169,6 +172,8 @@ Q_GUI_EXPORT int qt_defaultDpiX() if (!subScreens.isEmpty()) screen = subScreens.at(0); dpi = qRound(screen->width() / (screen->physicalWidth() / qreal(25.4))); +#elif defined(Q_OS_SYMBIAN) + dpi = S60->defaultDpiX; #endif // Q_WS_X11 return dpi; @@ -195,6 +200,8 @@ Q_GUI_EXPORT int qt_defaultDpiY() if (!subScreens.isEmpty()) screen = subScreens.at(0); dpi = qRound(screen->height() / (screen->physicalHeight() / qreal(25.4))); +#elif defined(Q_OS_SYMBIAN) + dpi = S60->defaultDpiY; #endif // Q_WS_X11 return dpi; @@ -210,7 +217,6 @@ QFontPrivate::QFontPrivate() rawMode(false), underline(false), overline(false), strikeOut(false), kerning(true), capital(0), letterSpacingIsAbsolute(false), scFont(0) { - ref = 1; #ifdef Q_WS_X11 if (QX11Info::display()) screen = QX11Info::appScreen(); @@ -230,7 +236,6 @@ QFontPrivate::QFontPrivate(const QFontPrivate &other) letterSpacing(other.letterSpacing), wordSpacing(other.wordSpacing), scFont(other.scFont) { - ref = 1; #ifdef Q_WS_WIN hdc = other.hdc; #endif @@ -307,7 +312,7 @@ QFontPrivate *QFontPrivate::smallCapsFontPrivate() const font.setPointSizeF(pointSize * .7); else font.setPixelSize((font.pixelSize() * 7 + 5) / 10); - scFont = font.d; + scFont = font.d.data(); if (scFont != this) scFont->ref.ref(); return scFont; @@ -408,11 +413,11 @@ QFontEngineData::~QFontEngineData() \brief The QFont class specifies a font used for drawing text. - \ingroup multimedia + \ingroup painting \ingroup appearance \ingroup shared - \ingroup text - \mainclass + \ingroup richtext-processing + When you create a QFont object you specify various attributes that you want the font to have. Qt will use the font with the specified @@ -718,8 +723,7 @@ QFont::QFont(const QFont &font, QPaintDevice *pd) d->dpi = dpi; d->screen = screen; } else { - d = font.d; - d->ref.ref(); + d = font.d.data(); } #ifdef Q_WS_WIN if (pd->devType() == QInternal::Printer && pd->getDC()) @@ -731,10 +735,8 @@ QFont::QFont(const QFont &font, QPaintDevice *pd) \internal */ QFont::QFont(QFontPrivate *data) - : resolve_mask(QFont::AllPropertiesResolved) + : d(data), resolve_mask(QFont::AllPropertiesResolved) { - d = data; - d->ref.ref(); } /*! \internal @@ -746,13 +748,13 @@ void QFont::detach() if (d->engineData) d->engineData->ref.deref(); d->engineData = 0; - if (d->scFont && d->scFont != d) + if (d->scFont && d->scFont != d.data()) d->scFont->ref.deref(); d->scFont = 0; return; } - qAtomicDetach(d); + d.detach(); } /*! @@ -761,16 +763,17 @@ void QFont::detach() \sa QApplication::setFont(), QApplication::font() */ QFont::QFont() - :d(QApplication::font().d), resolve_mask(0) + : d(QApplication::font().d.data()), resolve_mask(0) { - d->ref.ref(); } /*! Constructs a font object with the specified \a family, \a pointSize, \a weight and \a italic settings. - If \a pointSize is <= 0, it is set to 12. + If \a pointSize is zero or negative, the point size of the font + is set to a system-dependent default value. Generally, this is + 12 points, except on Symbian where it is 7 points. The \a family name may optionally also include a foundry name, e.g. "Helvetica [Cronyx]". If the \a family is @@ -783,12 +786,14 @@ QFont::QFont() setStyleHint() QApplication::font() */ QFont::QFont(const QString &family, int pointSize, int weight, bool italic) - :d(new QFontPrivate) + : d(new QFontPrivate()), resolve_mask(QFont::FamilyResolved) { - resolve_mask = QFont::FamilyResolved; - if (pointSize <= 0) { +#ifdef Q_OS_SYMBIAN + pointSize = 7; +#else pointSize = 12; +#endif } else { resolve_mask |= QFont::SizeResolved; } @@ -810,10 +815,8 @@ QFont::QFont(const QString &family, int pointSize, int weight, bool italic) Constructs a font that is a copy of \a font. */ QFont::QFont(const QFont &font) + : d(font.d.data()), resolve_mask(font.resolve_mask) { - d = font.d; - d->ref.ref(); - resolve_mask = font.resolve_mask; } /*! @@ -821,8 +824,6 @@ QFont::QFont(const QFont &font) */ QFont::~QFont() { - if (!d->ref.deref()) - delete d; } /*! @@ -830,7 +831,7 @@ QFont::~QFont() */ QFont &QFont::operator=(const QFont &font) { - qAtomicAssign(d, font.d); + d = font.d.data(); resolve_mask = font.resolve_mask; return *this; } @@ -1713,7 +1714,7 @@ QFont QFont::resolve(const QFont &other) const QFont font(*this); font.detach(); - font.d->resolve(resolve_mask, other.d); + font.d->resolve(resolve_mask, other.d.data()); return font; } @@ -2166,11 +2167,11 @@ QDataStream &operator<<(QDataStream &s, const QFont &font) s << (quint8) font.d->request.styleStrategy; s << (quint8) 0 << (quint8) font.d->request.weight - << get_font_bits(s.version(), font.d); + << get_font_bits(s.version(), font.d.data()); if (s.version() >= QDataStream::Qt_4_3) s << (quint16)font.d->request.stretch; if (s.version() >= QDataStream::Qt_4_4) - s << get_extended_font_bits(font.d); + s << get_extended_font_bits(font.d.data()); if (s.version() >= QDataStream::Qt_4_5) { s << font.d->letterSpacing.value(); s << font.d->wordSpacing.value(); @@ -2189,9 +2190,6 @@ QDataStream &operator<<(QDataStream &s, const QFont &font) */ QDataStream &operator>>(QDataStream &s, QFont &font) { - if (!font.d->ref.deref()) - delete font.d; - font.d = new QFontPrivate; font.resolve_mask = QFont::AllPropertiesResolved; @@ -2233,7 +2231,7 @@ QDataStream &operator>>(QDataStream &s, QFont &font) font.d->request.styleStrategy = styleStrategy; font.d->request.weight = weight; - set_font_bits(s.version(), bits, font.d); + set_font_bits(s.version(), bits, font.d.data()); if (s.version() >= QDataStream::Qt_4_3) { quint16 stretch; @@ -2244,7 +2242,7 @@ QDataStream &operator>>(QDataStream &s, QFont &font) if (s.version() >= QDataStream::Qt_4_4) { quint8 extendedBits; s >> extendedBits; - set_extended_font_bits(extendedBits, font.d); + set_extended_font_bits(extendedBits, font.d.data()); } if (s.version() >= QDataStream::Qt_4_5) { int value; @@ -2270,9 +2268,8 @@ QDataStream &operator>>(QDataStream &s, QFont &font) \brief The QFontInfo class provides general information about fonts. - \ingroup multimedia + \ingroup appearance \ingroup shared - \ingroup text The QFontInfo class provides the same access functions as QFont, e.g. family(), pointSize(), italic(), weight(), fixedPitch(), @@ -2326,7 +2323,7 @@ QDataStream &operator>>(QDataStream &s, QFont &font) that is not screen-compatible. */ QFontInfo::QFontInfo(const QFont &font) - : d(font.d) + : d(font.d.data()) { d->ref.ref(); } /*! @@ -2599,7 +2596,14 @@ QFontCache *QFontCache::instance() void QFontCache::cleanup() { - theFontCache()->setLocalData(0); + QThreadStorage<QFontCache *> *cache = 0; + QT_TRY { + cache = theFontCache(); + } QT_CATCH (const std::bad_alloc &) { + // no cache - just ignore + } + if (cache && cache->hasLocalData()) + cache->setLocalData(0); } #endif // QT_NO_THREAD @@ -2612,8 +2616,8 @@ QFontCache::QFontCache() QFontCache::~QFontCache() { { - EngineDataCache::Iterator it = engineDataCache.begin(), - end = engineDataCache.end(); + EngineDataCache::ConstIterator it = engineDataCache.constBegin(), + end = engineDataCache.constEnd(); while (it != end) { if (it.value()->ref == 0) delete it.value(); @@ -2623,8 +2627,8 @@ QFontCache::~QFontCache() ++it; } } - EngineCache::Iterator it = engineCache.begin(), - end = engineCache.end(); + EngineCache::ConstIterator it = engineCache.constBegin(), + end = engineCache.constEnd(); while (it != end) { if (--it.value().data->cache_count == 0) { if (it.value().data->ref == 0) { diff --git a/src/gui/text/qfont.h b/src/gui/text/qfont.h index e145a98..9fe660a 100644 --- a/src/gui/text/qfont.h +++ b/src/gui/text/qfont.h @@ -1,7 +1,6 @@ /**************************************************************************** ** ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** ** This file is part of the QtGui module of the Qt Toolkit. @@ -21,9 +20,10 @@ ** ensure the GNU Lesser General Public License version 2.1 requirements ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. ** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.1, included in the file LGPL_EXCEPTION.txt in this +** package. ** ** If you have questions regarding the use of this file, please contact ** Nokia at qt-info@nokia.com. @@ -44,6 +44,7 @@ #include <QtGui/qwindowdefs.h> #include <QtCore/qstring.h> +#include <QtCore/qsharedpointer.h> #if defined(Q_WS_X11) || defined(Q_WS_QWS) typedef struct FT_FaceRec_* FT_Face; @@ -306,13 +307,15 @@ private: friend class QPainterPath; friend class QTextItemInt; friend class QPicturePaintEngine; + friend class QPainterReplayer; + friend class QPaintBufferEngine; #ifndef QT_NO_DATASTREAM friend Q_GUI_EXPORT QDataStream &operator<<(QDataStream &, const QFont &); friend Q_GUI_EXPORT QDataStream &operator>>(QDataStream &, QFont &); #endif - QFontPrivate *d; + QExplicitlySharedDataPointer<QFontPrivate> d; uint resolve_mask; }; diff --git a/src/gui/text/qfont_mac.cpp b/src/gui/text/qfont_mac.cpp index 5a0faf9..238b798 100644 --- a/src/gui/text/qfont_mac.cpp +++ b/src/gui/text/qfont_mac.cpp @@ -1,7 +1,6 @@ /**************************************************************************** ** ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** ** This file is part of the QtGui module of the Qt Toolkit. @@ -21,9 +20,10 @@ ** ensure the GNU Lesser General Public License version 2.1 requirements ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. ** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.1, included in the file LGPL_EXCEPTION.txt in this +** package. ** ** If you have questions regarding the use of this file, please contact ** Nokia at qt-info@nokia.com. diff --git a/src/gui/text/qfont_p.h b/src/gui/text/qfont_p.h index d74f0b4..0835cad 100644 --- a/src/gui/text/qfont_p.h +++ b/src/gui/text/qfont_p.h @@ -1,7 +1,6 @@ /**************************************************************************** ** ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** ** This file is part of the QtGui module of the Qt Toolkit. @@ -21,9 +20,10 @@ ** ensure the GNU Lesser General Public License version 2.1 requirements ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. ** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.1, included in the file LGPL_EXCEPTION.txt in this +** package. ** ** If you have questions regarding the use of this file, please contact ** Nokia at qt-info@nokia.com. diff --git a/src/gui/text/qfont_qws.cpp b/src/gui/text/qfont_qws.cpp index 87c5b05..b1267b4 100644 --- a/src/gui/text/qfont_qws.cpp +++ b/src/gui/text/qfont_qws.cpp @@ -1,7 +1,6 @@ /**************************************************************************** ** ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** ** This file is part of the QtGui module of the Qt Toolkit. @@ -21,9 +20,10 @@ ** ensure the GNU Lesser General Public License version 2.1 requirements ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. ** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.1, included in the file LGPL_EXCEPTION.txt in this +** package. ** ** If you have questions regarding the use of this file, please contact ** Nokia at qt-info@nokia.com. diff --git a/src/gui/text/qfont_s60.cpp b/src/gui/text/qfont_s60.cpp new file mode 100644 index 0000000..45c0c06 --- /dev/null +++ b/src/gui/text/qfont_s60.cpp @@ -0,0 +1,94 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtGui of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.1, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qfont.h" +#include "qt_s60_p.h" +#include <private/qwindowsurface_s60_p.h> +#include "qmutex.h" + +QT_BEGIN_NAMESPACE + +#if 1 +#ifdef QT_NO_FREETYPE +Q_GLOBAL_STATIC(QMutex, lastResortFamilyMutex); +#endif // QT_NO_FREETYPE + +QString QFont::lastResortFamily() const +{ +#ifdef QT_NO_FREETYPE + QMutexLocker locker(lastResortFamilyMutex()); + static QString family; + if (family.isEmpty()) { + QS60WindowSurface::unlockBitmapHeap(); + CFont *font; + const TInt err = S60->screenDevice()->GetNearestFontInTwips(font, TFontSpec()); + Q_ASSERT(err == KErrNone); + const TFontSpec spec = font->FontSpecInTwips(); + family = QString((const QChar *)spec.iTypeface.iName.Ptr(), spec.iTypeface.iName.Length()); + S60->screenDevice()->ReleaseFont(font); + QS60WindowSurface::lockBitmapHeap(); + } + return family; +#else + // For the FreeType case we just hard code the face name, since otherwise on + // East Asian systems we may get a name for a stroke based (non-ttf) font. + + // TODO: Get the type face name in a proper way + + const bool isJapaneseOrChineseSystem = + User::Language() == ELangJapanese || User::Language() == ELangPrcChinese; + + return QLatin1String(isJapaneseOrChineseSystem?"Heisei Kaku Gothic S60":"Series 60 Sans"); +#endif // QT_NO_FREETYPE +} +#else // 0 +QString QFont::lastResortFamily() const +{ + return QLatin1String("Series 60 Sans"); +} +#endif // 0 + +QString QFont::defaultFamily() const +{ + return lastResortFamily(); +} + +QT_END_NAMESPACE diff --git a/src/gui/text/qfont_win.cpp b/src/gui/text/qfont_win.cpp index a141201..4ddea10 100644 --- a/src/gui/text/qfont_win.cpp +++ b/src/gui/text/qfont_win.cpp @@ -1,7 +1,6 @@ /**************************************************************************** ** ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** ** This file is part of the QtGui module of the Qt Toolkit. @@ -21,9 +20,10 @@ ** ensure the GNU Lesser General Public License version 2.1 requirements ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. ** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.1, included in the file LGPL_EXCEPTION.txt in this +** package. ** ** If you have questions regarding the use of this file, please contact ** Nokia at qt-info@nokia.com. @@ -39,11 +39,6 @@ ** ****************************************************************************/ -// the miscrosoft platform SDK says that the Unicode versions of -// TextOut and GetTextExtentsPoint32 are supported on all platforms, so we use them -// exclusively to simplify code, save a lot of conversions into the local encoding -// and have generally better unicode support :) - #include "qfont.h" #include "qfont_p.h" #include "qfontengine_p.h" @@ -67,8 +62,7 @@ extern HDC shared_dc(); // common dc for all fonts // ### maybe move to qapplication_win QFont qt_LOGFONTtoQFont(LOGFONT& lf, bool /*scale*/) { - QString family = QT_WA_INLINE(QString::fromUtf16((ushort*)lf.lfFaceName), - QString::fromLocal8Bit((char*)lf.lfFaceName)); + QString family = QString::fromWCharArray(lf.lfFaceName); QFont qf(family); qf.setItalic(lf.lfItalic); if (lf.lfWeight != FW_DONTCARE) { diff --git a/src/gui/text/qfont_x11.cpp b/src/gui/text/qfont_x11.cpp index 49e5d85..1253069 100644 --- a/src/gui/text/qfont_x11.cpp +++ b/src/gui/text/qfont_x11.cpp @@ -1,7 +1,6 @@ /**************************************************************************** ** ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** ** This file is part of the QtGui module of the Qt Toolkit. @@ -21,9 +20,10 @@ ** ensure the GNU Lesser General Public License version 2.1 requirements ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. ** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.1, included in the file LGPL_EXCEPTION.txt in this +** package. ** ** If you have questions regarding the use of this file, please contact ** Nokia at qt-info@nokia.com. diff --git a/src/gui/text/qfontdatabase.cpp b/src/gui/text/qfontdatabase.cpp index b19c043..78847ef 100644 --- a/src/gui/text/qfontdatabase.cpp +++ b/src/gui/text/qfontdatabase.cpp @@ -1,7 +1,6 @@ /**************************************************************************** ** ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** ** This file is part of the QtGui module of the Qt Toolkit. @@ -21,9 +20,10 @@ ** ensure the GNU Lesser General Public License version 2.1 requirements ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. ** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.1, included in the file LGPL_EXCEPTION.txt in this +** package. ** ** If you have questions regarding the use of this file, please contact ** Nokia at qt-info@nokia.com. @@ -56,6 +56,11 @@ #include <stdlib.h> #include <limits.h> +#if (defined(Q_WS_QWS) || defined(Q_OS_SYMBIAN)) && !defined(QT_NO_FREETYPE) +# include <ft2build.h> +# include FT_TRUETYPE_TABLES_H +#endif + // #define QFONTDATABASE_DEBUG #ifdef QFONTDATABASE_DEBUG # define FD_DEBUG qDebug @@ -76,9 +81,16 @@ QT_BEGIN_NAMESPACE +#define SMOOTH_SCALABLE 0xffff + extern int qt_defaultDpiY(); // in qfont.cpp -Q_GUI_EXPORT bool qt_enable_test_font = false; +bool qt_enable_test_font = false; + +Q_AUTOTEST_EXPORT void qt_setQtEnableTestFont(bool value) +{ + qt_enable_test_font = value; +} static int getFontWeight(const QString &weightString) { @@ -87,34 +99,34 @@ static int getFontWeight(const QString &weightString) // Test in decreasing order of commonness if (s == QLatin1String("medium") || s == QLatin1String("normal") - || s.compare(qApp->translate("QFontDatabase", "Normal"), Qt::CaseInsensitive) == 0) + || s.compare(QApplication::translate("QFontDatabase", "Normal"), Qt::CaseInsensitive) == 0) return QFont::Normal; if (s == QLatin1String("bold") - || s.compare(qApp->translate("QFontDatabase", "Bold"), Qt::CaseInsensitive) == 0) + || s.compare(QApplication::translate("QFontDatabase", "Bold"), Qt::CaseInsensitive) == 0) return QFont::Bold; if (s == QLatin1String("demibold") || s == QLatin1String("demi bold") - || s.compare(qApp->translate("QFontDatabase", "Demi Bold"), Qt::CaseInsensitive) == 0) + || s.compare(QApplication::translate("QFontDatabase", "Demi Bold"), Qt::CaseInsensitive) == 0) return QFont::DemiBold; if (s == QLatin1String("black") - || s.compare(qApp->translate("QFontDatabase", "Black"), Qt::CaseInsensitive) == 0) + || s.compare(QApplication::translate("QFontDatabase", "Black"), Qt::CaseInsensitive) == 0) return QFont::Black; if (s == QLatin1String("light")) return QFont::Light; if (s.contains(QLatin1String("bold")) - || s.contains(qApp->translate("QFontDatabase", "Bold"), Qt::CaseInsensitive)) { + || s.contains(QApplication::translate("QFontDatabase", "Bold"), Qt::CaseInsensitive)) { if (s.contains(QLatin1String("demi")) - || s.compare(qApp->translate("QFontDatabase", "Demi"), Qt::CaseInsensitive) == 0) + || s.compare(QApplication::translate("QFontDatabase", "Demi"), Qt::CaseInsensitive) == 0) return (int) QFont::DemiBold; return (int) QFont::Bold; } if (s.contains(QLatin1String("light")) - || s.compare(qApp->translate("QFontDatabase", "Light"), Qt::CaseInsensitive) == 0) + || s.compare(QApplication::translate("QFontDatabase", "Light"), Qt::CaseInsensitive) == 0) return (int) QFont::Light; if (s.contains(QLatin1String("black")) - || s.compare(qApp->translate("QFontDatabase", "Black"), Qt::CaseInsensitive) == 0) + || s.compare(QApplication::translate("QFontDatabase", "Black"), Qt::CaseInsensitive) == 0) return (int) QFont::Black; return (int) QFont::Normal; @@ -141,10 +153,10 @@ struct QtFontSize QtFontEncoding *encodingID(int id, uint xpoint = 0, uint xres = 0, uint yres = 0, uint avgwidth = 0, bool add = false); #endif // Q_WS_X11 -#ifdef Q_WS_QWS +#if defined(Q_WS_QWS) || defined(Q_OS_SYMBIAN) QByteArray fileName; int fileIndex; -#endif +#endif // defined(Q_WS_QWS) || defined(Q_OS_SYMBIAN) }; @@ -160,10 +172,13 @@ QtFontEncoding *QtFontSize::encodingID(int id, uint xpoint, uint xres, if (!add) return 0; - if (!(count % 4)) - encodings = (QtFontEncoding *) + if (!(count % 4)) { + QtFontEncoding *newEncodings = (QtFontEncoding *) realloc(encodings, (((count+4) >> 2) << 2) * sizeof(QtFontEncoding)); + Q_CHECK_PTR(newEncodings); + encodings = newEncodings; + } encodings[count].encoding = id; encodings[count].xpoint = xpoint; encodings[count].xres = xres; @@ -215,12 +230,14 @@ struct QtFontStyle delete [] weightName; delete [] setwidthName; #endif -#if defined(Q_WS_X11) || defined(Q_WS_QWS) - while (count--) { +#if defined(Q_WS_X11) || defined(Q_WS_QWS) || defined(Q_OS_SYMBIAN) + while (count) { + // bitfield count-- in while condition does not work correctly in mwccsym2 + count--; #ifdef Q_WS_X11 free(pixelSizes[count].encodings); #endif -#ifdef Q_WS_QWS +#if defined(Q_WS_QWS) || defined(Q_OS_SYMBIAN) pixelSizes[count].fileName.~QByteArray(); #endif } @@ -238,7 +255,7 @@ struct QtFontStyle const char *weightName; const char *setwidthName; #endif // Q_WS_X11 -#ifdef Q_WS_QWS +#if defined(Q_WS_QWS) || defined(Q_OS_SYMBIAN) bool antialiased; #endif @@ -251,10 +268,10 @@ QtFontStyle::Key::Key(const QString &styleString) weight = getFontWeight(styleString); if (styleString.contains(QLatin1String("Italic")) - || styleString.contains(qApp->translate("QFontDatabase", "Italic"))) + || styleString.contains(QApplication::translate("QFontDatabase", "Italic"))) style = QFont::StyleItalic; else if (styleString.contains(QLatin1String("Oblique")) - || styleString.contains(qApp->translate("QFontDatabase", "Oblique"))) + || styleString.contains(QApplication::translate("QFontDatabase", "Oblique"))) style = QFont::StyleOblique; } @@ -267,16 +284,19 @@ QtFontSize *QtFontStyle::pixelSize(unsigned short size, bool add) if (!add) return 0; - if (!(count % 8)) - pixelSizes = (QtFontSize *) + if (!(count % 8)) { + QtFontSize *newPixelSizes = (QtFontSize *) realloc(pixelSizes, (((count+8) >> 3) << 3) * sizeof(QtFontSize)); + Q_CHECK_PTR(newPixelSizes); + pixelSizes = newPixelSizes; + } pixelSizes[count].pixelSize = size; #ifdef Q_WS_X11 pixelSizes[count].count = 0; pixelSizes[count].encodings = 0; #endif -#ifdef Q_WS_QWS +#if defined(Q_WS_QWS) || defined(Q_OS_SYMBIAN) new (&pixelSizes[count].fileName) QByteArray; pixelSizes[count].fileIndex = 0; #endif @@ -321,12 +341,16 @@ QtFontStyle *QtFontFoundry::style(const QtFontStyle::Key &key, bool create) return 0; // qDebug("adding key (weight=%d, style=%d, oblique=%d stretch=%d) at %d", key.weight, key.style, key.oblique, key.stretch, pos); - if (!(count % 8)) - styles = (QtFontStyle **) + if (!(count % 8)) { + QtFontStyle **newStyles = (QtFontStyle **) realloc(styles, (((count+8) >> 3) << 3) * sizeof(QtFontStyle *)); + Q_CHECK_PTR(newStyles); + styles = newStyles; + } + QtFontStyle *style = new QtFontStyle(key); memmove(styles + pos + 1, styles + pos, (count-pos)*sizeof(QtFontStyle *)); - styles[pos] = new QtFontStyle(key); + styles[pos] = style; count++; return styles[pos]; } @@ -358,7 +382,7 @@ struct QtFontFamily fixedPitchComputed(false), #endif name(n), count(0), foundries(0) -#if defined(Q_WS_QWS) +#if defined(Q_WS_QWS) || defined(Q_OS_SYMBIAN) && !defined(QT_NO_FREETYPE) , bogusWritingSystems(false) #endif { @@ -388,7 +412,7 @@ struct QtFontFamily #endif QString name; -#ifdef Q_WS_X11 +#if defined(Q_WS_X11) || defined(Q_OS_SYMBIAN) && !defined(QT_NO_FREETYPE) QByteArray fontFilename; int fontFileIndex; #endif @@ -398,7 +422,7 @@ struct QtFontFamily int count; QtFontFoundry **foundries; -#ifdef Q_WS_QWS +#if defined(Q_WS_QWS) || defined(Q_OS_SYMBIAN) && !defined(QT_NO_FREETYPE) bool bogusWritingSystems; QStringList fallbackFamilies; #endif @@ -431,10 +455,13 @@ QtFontFoundry *QtFontFamily::foundry(const QString &f, bool create) if (!create) return 0; - if (!(count % 8)) - foundries = (QtFontFoundry **) + if (!(count % 8)) { + QtFontFoundry **newFoundries = (QtFontFoundry **) realloc(foundries, (((count+8) >> 3) << 3) * sizeof(QtFontFoundry *)); + Q_CHECK_PTR(newFoundries); + foundries = newFoundries; + } foundries[count] = new QtFontFoundry(f); return foundries[count++]; @@ -442,7 +469,7 @@ QtFontFoundry *QtFontFamily::foundry(const QString &f, bool create) // ### copied to tools/makeqpf/qpf2.cpp -#if (defined(Q_WS_QWS) && !defined(QT_NO_FREETYPE)) || defined(Q_WS_WIN) || (defined(Q_WS_MAC) && !defined(QT_MAC_USE_COCOA)) +#if (defined(Q_WS_QWS) && !defined(QT_NO_FREETYPE)) || defined(Q_WS_WIN) || defined(Q_OS_SYMBIAN) || (defined(Q_WS_MAC) && !defined(QT_MAC_USE_COCOA)) // see the Unicode subset bitfields in the MSDN docs static int requiredUnicodeBits[QFontDatabase::WritingSystemsCount][2] = { // Any, @@ -563,6 +590,15 @@ static QList<QFontDatabase::WritingSystem> determineWritingSystemsFromTrueTypeBi } #endif +#if defined(Q_OS_SYMBIAN) && defined(QT_NO_FREETYPE) +// class with virtual destructor, derived in qfontdatabase_s60.cpp +class QFontDatabaseS60Store +{ +public: + virtual ~QFontDatabaseS60Store() {} +}; +#endif + class QFontDatabasePrivate { public: @@ -571,6 +607,9 @@ public: #if defined(Q_WS_QWS) , stream(0) #endif +#if defined(Q_OS_SYMBIAN) && defined(QT_NO_FREETYPE) + , s60Store(0) +#endif { } ~QFontDatabasePrivate() { free(); @@ -582,6 +621,12 @@ public: ::free(families); families = 0; count = 0; +#if defined(Q_OS_SYMBIAN) && defined(QT_NO_FREETYPE) + if (s60Store) { + delete s60Store; + s60Store = 0; + } +#endif // don't clear the memory fonts! } @@ -609,17 +654,22 @@ public: #if defined(Q_WS_QWS) bool loadFromCache(const QString &fontPath); + void addQPF2File(const QByteArray &file); +#endif // Q_WS_QWS +#if defined(Q_WS_QWS) || defined(Q_OS_SYMBIAN) && !defined(QT_NO_FREETYPE) void addFont(const QString &familyname, const char *foundryname, int weight, bool italic, int pixelSize, const QByteArray &file, int fileIndex, bool antialiased, const QList<QFontDatabase::WritingSystem> &writingSystems = QList<QFontDatabase::WritingSystem>()); - void addQPF2File(const QByteArray &file); #ifndef QT_NO_FREETYPE QStringList addTTFile(const QByteArray &file, const QByteArray &fontData = QByteArray()); +#endif // QT_NO_FREETYPE #endif - +#if defined(Q_WS_QWS) QDataStream *stream; QStringList fallbackFamilies; +#elif defined(Q_OS_SYMBIAN) && defined(QT_NO_FREETYPE) + const QFontDatabaseS60Store *s60Store; #endif }; @@ -654,17 +704,133 @@ QtFontFamily *QFontDatabasePrivate::family(const QString &f, bool create) pos++; // qDebug("adding family %s at %d total=%d", f.latin1(), pos, count); - if (!(count % 8)) - families = (QtFontFamily **) + if (!(count % 8)) { + QtFontFamily **newFamilies = (QtFontFamily **) realloc(families, (((count+8) >> 3) << 3) * sizeof(QtFontFamily *)); + Q_CHECK_PTR(newFamilies); + families = newFamilies; + } + QtFontFamily *family = new QtFontFamily(f); memmove(families + pos + 1, families + pos, (count-pos)*sizeof(QtFontFamily *)); - families[pos] = new QtFontFamily(f); + families[pos] = family; count++; return families[pos]; } +#if defined(Q_WS_QWS) || defined(Q_OS_SYMBIAN) && !defined(QT_NO_FREETYPE) +void QFontDatabasePrivate::addFont(const QString &familyname, const char *foundryname, int weight, bool italic, int pixelSize, + const QByteArray &file, int fileIndex, bool antialiased, + const QList<QFontDatabase::WritingSystem> &writingSystems) +{ +// qDebug() << "Adding font" << familyname << weight << italic << pixelSize << file << fileIndex << antialiased; + QtFontStyle::Key styleKey; + styleKey.style = italic ? QFont::StyleItalic : QFont::StyleNormal; + styleKey.weight = weight; + styleKey.stretch = 100; + QtFontFamily *f = family(familyname, true); + + if (writingSystems.isEmpty()) { + for (int ws = 1; ws < QFontDatabase::WritingSystemsCount; ++ws) { + f->writingSystems[ws] = QtFontFamily::Supported; + } + f->bogusWritingSystems = true; + } else { + for (int i = 0; i < writingSystems.count(); ++i) { + f->writingSystems[writingSystems.at(i)] = QtFontFamily::Supported; + } + } + + QtFontFoundry *foundry = f->foundry(QString::fromLatin1(foundryname), true); + QtFontStyle *style = foundry->style(styleKey, true); + style->smoothScalable = (pixelSize == 0); + style->antialiased = antialiased; + QtFontSize *size = style->pixelSize(pixelSize?pixelSize:SMOOTH_SCALABLE, true); + size->fileName = file; + size->fileIndex = fileIndex; + +#if defined(Q_WS_QWS) + if (stream) { + *stream << familyname << foundry->name << weight << quint8(italic) << pixelSize + << file << fileIndex << quint8(antialiased); + *stream << quint8(writingSystems.count()); + for (int i = 0; i < writingSystems.count(); ++i) + *stream << quint8(writingSystems.at(i)); + } +#else // ..in case of defined(Q_OS_SYMBIAN) && !defined(QT_NO_FREETYPE) + f->fontFilename = file; + f->fontFileIndex = fileIndex; +#endif +} +#endif + +#if (defined(Q_WS_QWS) || defined(Q_OS_SYMBIAN)) && !defined(QT_NO_FREETYPE) +QStringList QFontDatabasePrivate::addTTFile(const QByteArray &file, const QByteArray &fontData) +{ + QStringList families; + extern FT_Library qt_getFreetype(); + FT_Library library = qt_getFreetype(); + + int index = 0; + int numFaces = 0; + do { + FT_Face face; + FT_Error error; + if (!fontData.isEmpty()) { + error = FT_New_Memory_Face(library, (const FT_Byte *)fontData.constData(), fontData.size(), index, &face); + } else { + error = FT_New_Face(library, file, index, &face); + } + if (error != FT_Err_Ok) { + qDebug() << "FT_New_Face failed with index" << index << ":" << hex << error; + break; + } + numFaces = face->num_faces; + + int weight = QFont::Normal; + bool italic = face->style_flags & FT_STYLE_FLAG_ITALIC; + + if (face->style_flags & FT_STYLE_FLAG_BOLD) + weight = QFont::Bold; + + QList<QFontDatabase::WritingSystem> writingSystems; + // detect symbol fonts + for (int i = 0; i < face->num_charmaps; ++i) { + FT_CharMap cm = face->charmaps[i]; + if (cm->encoding == ft_encoding_adobe_custom + || cm->encoding == ft_encoding_symbol) { + writingSystems.append(QFontDatabase::Symbol); + break; + } + } + if (writingSystems.isEmpty()) { + TT_OS2 *os2 = (TT_OS2 *)FT_Get_Sfnt_Table(face, ft_sfnt_os2); + if (os2) { + quint32 unicodeRange[4] = { + os2->ulUnicodeRange1, os2->ulUnicodeRange2, os2->ulUnicodeRange3, os2->ulUnicodeRange4 + }; + quint32 codePageRange[2] = { + os2->ulCodePageRange1, os2->ulCodePageRange2 + }; + + writingSystems = determineWritingSystemsFromTrueTypeBits(unicodeRange, codePageRange); + //for (int i = 0; i < writingSystems.count(); ++i) + // qDebug() << QFontDatabase::writingSystemName(writingSystems.at(i)); + } + } + + QString family = QString::fromAscii(face->family_name); + families.append(family); + addFont(family, /*foundry*/ "", weight, italic, + /*pixelsize*/ 0, file, index, /*antialias*/ true, writingSystems); + + FT_Done_Face(face); + ++index; + } while (index < numFaces); + return families; +} +#endif static const int scriptForWritingSystem[] = { QUnicodeTables::Common, // Any @@ -792,7 +958,7 @@ static void initFontDef(const QtFontDesc &desc, const QFontDef &request, QFontDe if (! desc.foundry->name.isEmpty() && desc.family->count > 1) { fontDef->family += QString::fromLatin1(" ["); fontDef->family += desc.foundry->name; - fontDef->family += QString::fromLatin1("]"); + fontDef->family += QLatin1Char(']'); } if (desc.style->smoothScalable) @@ -814,7 +980,7 @@ static void initFontDef(const QtFontDesc &desc, const QFontDef &request, QFontDe #endif #endif -#if defined(Q_WS_X11) || defined(Q_WS_WIN) +#if defined(Q_WS_X11) || defined(Q_WS_WIN) || defined(Q_OS_SYMBIAN) static void getEngineData(const QFontPrivate *d, const QFontCache::Key &key) { // look for the requested font in the engine data cache @@ -866,8 +1032,6 @@ QMutex *qt_fontdatabase_mutex() return fontDatabaseMutex(); } -#define SMOOTH_SCALABLE 0xffff - QT_BEGIN_INCLUDE_NAMESPACE #if defined(Q_WS_X11) # include "qfontdatabase_x11.cpp" @@ -877,6 +1041,8 @@ QT_BEGIN_INCLUDE_NAMESPACE # include "qfontdatabase_win.cpp" #elif defined(Q_WS_QWS) # include "qfontdatabase_qws.cpp" +#elif defined(Q_OS_SYMBIAN) +# include "qfontdatabase_s60.cpp" #endif QT_END_INCLUDE_NAMESPACE @@ -1249,21 +1415,21 @@ static QString styleStringHelper(int weight, QFont::Style style) { QString result; if (weight >= QFont::Black) - result = qApp->translate("QFontDatabase", "Black"); + result = QApplication::translate("QFontDatabase", "Black"); else if (weight >= QFont::Bold) - result = qApp->translate("QFontDatabase", "Bold"); + result = QApplication::translate("QFontDatabase", "Bold"); else if (weight >= QFont::DemiBold) - result = qApp->translate("QFontDatabase", "Demi Bold"); + result = QApplication::translate("QFontDatabase", "Demi Bold"); else if (weight < QFont::Normal) - result = qApp->translate("QFontDatabase", "Light"); + result = QApplication::translate("QFontDatabase", "Light"); if (style == QFont::StyleItalic) - result += QLatin1Char(' ') + qApp->translate("QFontDatabase", "Italic"); + result += QLatin1Char(' ') + QApplication::translate("QFontDatabase", "Italic"); else if (style == QFont::StyleOblique) - result += QLatin1Char(' ') + qApp->translate("QFontDatabase", "Oblique"); + result += QLatin1Char(' ') + QApplication::translate("QFontDatabase", "Oblique"); if (result.isEmpty()) - result = qApp->translate("QFontDatabase", "Normal"); + result = QApplication::translate("QFontDatabase", "Normal"); return result.simplified(); } @@ -1295,9 +1461,7 @@ QString QFontDatabase::styleString(const QFontInfo &fontInfo) \brief The QFontDatabase class provides information about the fonts available in the underlying window system. - \ingroup environment - \ingroup multimedia - \ingroup text + \ingroup appearance The most common uses of this class are to query the database for the list of font families() and for the pointSizes() and styles() @@ -1495,7 +1659,7 @@ QStringList QFontDatabase::families(WritingSystem writingSystem) const if (!foundry.isEmpty()) { str += QLatin1String(" ["); str += foundry; - str += QLatin1String("]"); + str += QLatin1Char(']'); } flist.append(str); } @@ -2067,7 +2231,7 @@ QString QFontDatabase::writingSystemName(WritingSystem writingSystem) Q_ASSERT_X(false, "QFontDatabase::writingSystemName", "invalid 'writingSystem' parameter"); break; } - return qApp ? qApp->translate("QFontDatabase", name) : QString::fromLatin1(name); + return QApplication::translate("QFontDatabase", name); } @@ -2254,7 +2418,16 @@ QString QFontDatabase::writingSystemSample(WritingSystem writingSystem) sample += QChar(0xac2f); break; case Vietnamese: + { + static const char vietnameseUtf8[] = { + char(0xef), char(0xbb), char(0xbf), char(0xe1), char(0xbb), char(0x97), + char(0xe1), char(0xbb), char(0x99), + char(0xe1), char(0xbb), char(0x91), + char(0xe1), char(0xbb), char(0x93), + }; + sample += QString::fromUtf8(vietnameseUtf8, sizeof(vietnameseUtf8)); break; + } case Ogham: sample += QChar(0x1681); sample += QChar(0x1682); @@ -2418,7 +2591,7 @@ QStringList QFontDatabase::applicationFontFamilies(int id) \sa removeApplicationFont(), addApplicationFont(), addApplicationFontFromData() */ -/*! +/*! \fn bool QFontDatabase::supportsThreadedFontRendering() \since 4.4 @@ -2427,7 +2600,7 @@ QStringList QFontDatabase::applicationFontFamilies(int id) means that all QPainter::drawText() calls outside the GUI thread will not produce readable output. - \sa threads.html#painting-in-threads + \sa {Thread-Support in Qt Modules#Painting In Threads}{Painting In Threads} */ diff --git a/src/gui/text/qfontdatabase.h b/src/gui/text/qfontdatabase.h index c5cd013..e62bb31 100644 --- a/src/gui/text/qfontdatabase.h +++ b/src/gui/text/qfontdatabase.h @@ -1,7 +1,6 @@ /**************************************************************************** ** ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** ** This file is part of the QtGui module of the Qt Toolkit. @@ -21,9 +20,10 @@ ** ensure the GNU Lesser General Public License version 2.1 requirements ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. ** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.1, included in the file LGPL_EXCEPTION.txt in this +** package. ** ** If you have questions regarding the use of this file, please contact ** Nokia at qt-info@nokia.com. @@ -151,7 +151,7 @@ public: private: static void createDatabase(); static void parseFontName(const QString &name, QString &foundry, QString &family); -#if defined(Q_WS_QWS) +#if defined(Q_WS_QWS) || defined(Q_OS_SYMBIAN) static QFontEngine *findFont(int script, const QFontPrivate *fp, const QFontDef &request); #endif static void load(const QFontPrivate *d, int script); @@ -165,6 +165,7 @@ private: friend class QFontDialogPrivate; friend class QFontEngineMultiXLFD; friend class QFontEngineMultiQWS; + friend class QFontEngineMultiS60; QFontDatabasePrivate *d; }; diff --git a/src/gui/text/qfontdatabase_mac.cpp b/src/gui/text/qfontdatabase_mac.cpp index d65910c..fc2fe7d 100644 --- a/src/gui/text/qfontdatabase_mac.cpp +++ b/src/gui/text/qfontdatabase_mac.cpp @@ -1,7 +1,6 @@ /**************************************************************************** ** ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** ** This file is part of the QtGui module of the Qt Toolkit. @@ -21,9 +20,10 @@ ** ensure the GNU Lesser General Public License version 2.1 requirements ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. ** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.1, included in the file LGPL_EXCEPTION.txt in this +** package. ** ** If you have questions regarding the use of this file, please contact ** Nokia at qt-info@nokia.com. diff --git a/src/gui/text/qfontdatabase_qws.cpp b/src/gui/text/qfontdatabase_qws.cpp index 468b45b..0a9630f 100644 --- a/src/gui/text/qfontdatabase_qws.cpp +++ b/src/gui/text/qfontdatabase_qws.cpp @@ -1,7 +1,6 @@ /**************************************************************************** ** ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** ** This file is part of the QtGui module of the Qt Toolkit. @@ -21,9 +20,10 @@ ** ensure the GNU Lesser General Public License version 2.1 requirements ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. ** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.1, included in the file LGPL_EXCEPTION.txt in this +** package. ** ** If you have questions regarding the use of this file, please contact ** Nokia at qt-info@nokia.com. @@ -50,14 +50,15 @@ #include <ft2build.h> #include FT_FREETYPE_H -#include FT_TRUETYPE_TABLES_H #endif #include "qfontengine_qpf_p.h" #include "private/qfactoryloader_p.h" +#include "private/qcore_unix_p.h" // overrides QT_OPEN #include "qabstractfontengine_qws.h" #include "qabstractfontengine_p.h" #include <qdatetime.h> +#include "qplatformdefs.h" // for mmap #include <stdlib.h> @@ -81,44 +82,7 @@ Q_GLOBAL_STATIC_WITH_ARGS(QFactoryLoader, loader, const quint8 DatabaseVersion = 4; -void QFontDatabasePrivate::addFont(const QString &familyname, const char *foundryname, int weight, bool italic, int pixelSize, - const QByteArray &file, int fileIndex, bool antialiased, - const QList<QFontDatabase::WritingSystem> &writingSystems) -{ -// qDebug() << "Adding font" << familyname << weight << italic << pixelSize << file << fileIndex << antialiased; - QtFontStyle::Key styleKey; - styleKey.style = italic ? QFont::StyleItalic : QFont::StyleNormal; - styleKey.weight = weight; - styleKey.stretch = 100; - QtFontFamily *f = family(familyname, true); - - if (writingSystems.isEmpty()) { - for (int ws = 1; ws < QFontDatabase::WritingSystemsCount; ++ws) { - f->writingSystems[ws] = QtFontFamily::Supported; - } - f->bogusWritingSystems = true; - } else { - for (int i = 0; i < writingSystems.count(); ++i) { - f->writingSystems[writingSystems.at(i)] = QtFontFamily::Supported; - } - } - - QtFontFoundry *foundry = f->foundry(QString::fromLatin1(foundryname), true); - QtFontStyle *style = foundry->style(styleKey, true); - style->smoothScalable = (pixelSize == 0); - style->antialiased = antialiased; - QtFontSize *size = style->pixelSize(pixelSize?pixelSize:SMOOTH_SCALABLE, true); - size->fileName = file; - size->fileIndex = fileIndex; - - if (stream) { - *stream << familyname << foundry->name << weight << quint8(italic) << pixelSize - << file << fileIndex << quint8(antialiased); - *stream << quint8(writingSystems.count()); - for (int i = 0; i < writingSystems.count(); ++i) - *stream << quint8(writingSystems.at(i)); - } -} +// QFontDatabasePrivate::addFont() went into qfontdatabase.cpp #ifndef QT_NO_QWS_QPF2 void QFontDatabasePrivate::addQPF2File(const QByteArray &file) @@ -127,7 +91,7 @@ void QFontDatabasePrivate::addQPF2File(const QByteArray &file) struct stat st; if (stat(file.constData(), &st)) return; - int f = ::open(file, O_RDONLY); + int f = QT_OPEN(file, O_RDONLY, 0); if (f < 0) return; const uchar *data = (const uchar *)mmap(0, st.st_size, PROT_READ, MAP_SHARED, f, 0); @@ -175,77 +139,12 @@ void QFontDatabasePrivate::addQPF2File(const QByteArray &file) #endif } #ifndef QT_FONTS_ARE_RESOURCES - ::close(f); + QT_CLOSE(f); #endif } -#endif - -#ifndef QT_NO_FREETYPE -QStringList QFontDatabasePrivate::addTTFile(const QByteArray &file, const QByteArray &fontData) -{ - QStringList families; - extern FT_Library qt_getFreetype(); - FT_Library library = qt_getFreetype(); - - int index = 0; - int numFaces = 0; - do { - FT_Face face; - FT_Error error; - if (!fontData.isEmpty()) { - error = FT_New_Memory_Face(library, (const FT_Byte *)fontData.constData(), fontData.size(), index, &face); - } else { - error = FT_New_Face(library, file, index, &face); - } - if (error != FT_Err_Ok) { - qDebug() << "FT_New_Face failed with index" << index << ":" << hex << error; - break; - } - numFaces = face->num_faces; +#endif // QT_NO_QWS_QPF2 - int weight = QFont::Normal; - bool italic = face->style_flags & FT_STYLE_FLAG_ITALIC; - - if (face->style_flags & FT_STYLE_FLAG_BOLD) - weight = QFont::Bold; - - QList<QFontDatabase::WritingSystem> writingSystems; - // detect symbol fonts - for (int i = 0; i < face->num_charmaps; ++i) { - FT_CharMap cm = face->charmaps[i]; - if (cm->encoding == ft_encoding_adobe_custom - || cm->encoding == ft_encoding_symbol) { - writingSystems.append(QFontDatabase::Symbol); - break; - } - } - if (writingSystems.isEmpty()) { - TT_OS2 *os2 = (TT_OS2 *)FT_Get_Sfnt_Table(face, ft_sfnt_os2); - if (os2) { - quint32 unicodeRange[4] = { - os2->ulUnicodeRange1, os2->ulUnicodeRange2, os2->ulUnicodeRange3, os2->ulUnicodeRange4 - }; - quint32 codePageRange[2] = { - os2->ulCodePageRange1, os2->ulCodePageRange2 - }; - - writingSystems = determineWritingSystemsFromTrueTypeBits(unicodeRange, codePageRange); - //for (int i = 0; i < writingSystems.count(); ++i) - // qDebug() << QFontDatabase::writingSystemName(writingSystems.at(i)); - } - } - - QString family = QString::fromAscii(face->family_name); - families.append(family); - addFont(family, /*foundry*/ "", weight, italic, - /*pixelsize*/ 0, file, index, /*antialias*/ true, writingSystems); - - FT_Done_Face(face); - ++index; - } while (index < numFaces); - return families; -} -#endif +// QFontDatabasePrivate::addTTFile() went into qfontdatabase.cpp static void registerFont(QFontDatabasePrivate::ApplicationFont *fnt); @@ -358,7 +257,7 @@ static QString qwsFontPath() return fontpath; } -#ifdef QFONTDATABASE_DEBUG +#if defined(QFONTDATABASE_DEBUG) && defined(QT_FONTS_ARE_RESOURCES) class FriendlyResource : public QResource { public: @@ -669,19 +568,19 @@ QFontEngine *loadSingleEngine(int script, const QFontPrivate *fp, QFontEngineQPF *fe = new QFontEngineQPF(request, res.data(), res.size()); if (fe->isValid()) return fe; - qDebug() << "fontengine is not valid! " << size->fileName; delete fe; + qDebug() << "fontengine is not valid! " << size->fileName; } else { qDebug() << "Resource not valid" << size->fileName; } #else - int f = ::open(size->fileName, O_RDONLY); + int f = ::open(size->fileName, O_RDONLY, 0); if (f >= 0) { QFontEngineQPF *fe = new QFontEngineQPF(request, f); if (fe->isValid()) return fe; - qDebug() << "fontengine is not valid!"; delete fe; // will close f + qDebug() << "fontengine is not valid!"; } #endif } else @@ -692,73 +591,74 @@ QFontEngine *loadSingleEngine(int script, const QFontPrivate *fp, QFontDef def = request; def.pixelSize = pixelSize; +#ifdef QT_NO_QWS_SHARE_FONTS + bool shareFonts = false; +#else static bool dontShareFonts = !qgetenv("QWS_NO_SHARE_FONTS").isEmpty(); bool shareFonts = !dontShareFonts; +#endif - QFontEngine *engine = 0; + QScopedPointer<QFontEngine> engine; #ifndef QT_NO_LIBRARY QFontEngineFactoryInterface *factory = qobject_cast<QFontEngineFactoryInterface *>(loader()->instance(foundry->name)); - if (factory) { - QFontEngineInfo info; - info.setFamily(request.family); - info.setPixelSize(request.pixelSize); - info.setStyle(QFont::Style(request.style)); - info.setWeight(request.weight); - // #### antialiased - - QAbstractFontEngine *customEngine = factory->create(info); - if (customEngine) { - engine = new QProxyFontEngine(customEngine, def); - - if (shareFonts) { - QVariant hint = customEngine->fontProperty(QAbstractFontEngine::CacheGlyphsHint); - if (hint.isValid()) - shareFonts = hint.toBool(); - else - shareFonts = (pixelSize < 64); - } + if (factory) { + QFontEngineInfo info; + info.setFamily(request.family); + info.setPixelSize(request.pixelSize); + info.setStyle(QFont::Style(request.style)); + info.setWeight(request.weight); + // #### antialiased + + QAbstractFontEngine *customEngine = factory->create(info); + if (customEngine) { + engine.reset(new QProxyFontEngine(customEngine, def)); + + if (shareFonts) { + QVariant hint = customEngine->fontProperty(QAbstractFontEngine::CacheGlyphsHint); + if (hint.isValid()) + shareFonts = hint.toBool(); + else + shareFonts = (pixelSize < 64); } + } } #endif // QT_NO_LIBRARY - if (!engine && !file.isEmpty() && QFile::exists(file) || privateDb()->isApplicationFont(file)) { + if ((engine.isNull() && !file.isEmpty() && QFile::exists(file)) || privateDb()->isApplicationFont(file)) { QFontEngine::FaceId faceId; faceId.filename = file.toLocal8Bit(); faceId.index = size->fileIndex; #ifndef QT_NO_FREETYPE - QFontEngineFT *fte = new QFontEngineFT(def); + QScopedPointer<QFontEngineFT> fte(new QFontEngineFT(def)); if (fte->init(faceId, style->antialiased, style->antialiased ? QFontEngineFT::Format_A8 : QFontEngineFT::Format_Mono)) { #ifdef QT_NO_QWS_QPF2 - return fte; + return fte.take(); #else - engine = fte; // try to distinguish between bdf and ttf fonts we can pre-render // and don't try to share outline fonts shareFonts = shareFonts && !fte->defaultGlyphs()->outline_drawing && !fte->getSfntTable(MAKE_TAG('h', 'e', 'a', 'd')).isEmpty(); + engine.reset(fte.take()); #endif - } else { - delete fte; } #endif // QT_NO_FREETYPE } - if (engine) { + if (!engine.isNull()) { #if !defined(QT_NO_QWS_QPF2) && !defined(QT_FONTS_ARE_RESOURCES) if (shareFonts) { - QFontEngineQPF *fe = new QFontEngineQPF(def, -1, engine); - engine = 0; + QScopedPointer<QFontEngineQPF> fe(new QFontEngineQPF(def, -1, engine.data())); + engine.take(); if (fe->isValid()) - return fe; + return fe.take(); qWarning("Initializing QFontEngineQPF failed for %s", qPrintable(file)); - engine = fe->takeRenderingEngine(); - delete fe; + engine.reset(fe->takeRenderingEngine()); } #endif - return engine; + return engine.take(); } } else { @@ -766,8 +666,8 @@ QFontEngine *loadSingleEngine(int script, const QFontPrivate *fp, QString fn = qwsFontPath(); fn += QLatin1Char('/'); fn += family->name.toLower() - + QLatin1String("_") + QString::number(pixelSize*10) - + QLatin1String("_") + QString::number(style->key.weight) + + QLatin1Char('_') + QString::number(pixelSize*10) + + QLatin1Char('_') + QString::number(style->key.weight) + (style->key.style == QFont::StyleItalic ? QLatin1String("i.qpf") : QLatin1String(".qpf")); //###rotation ### @@ -785,20 +685,22 @@ QFontEngine *loadEngine(int script, const QFontPrivate *fp, QtFontFamily *family, QtFontFoundry *foundry, QtFontStyle *style, QtFontSize *size) { - QFontEngine *fe = loadSingleEngine(script, fp, request, family, foundry, - style, size); - if (fe + QScopedPointer<QFontEngine> engine(loadSingleEngine(script, fp, request, family, foundry, + style, size)); + if (!engine.isNull() && script == QUnicodeTables::Common - && !(request.styleStrategy & QFont::NoFontMerging) && !fe->symbol) { + && !(request.styleStrategy & QFont::NoFontMerging) && !engine->symbol) { QStringList fallbacks = privateDb()->fallbackFamilies; if (family && !family->fallbackFamilies.isEmpty()) fallbacks = family->fallbackFamilies; - fe = new QFontEngineMultiQWS(fe, script, fallbacks); + QFontEngine *fe = new QFontEngineMultiQWS(engine.data(), script, fallbacks); + engine.take(); + engine.reset(fe); } - return fe; + return engine.take(); } static void registerFont(QFontDatabasePrivate::ApplicationFont *fnt) @@ -860,21 +762,21 @@ QFontDatabase::findFont(int script, const QFontPrivate *fp, if (!privateDb()->count) initializeDb(); - QFontEngine *fe = 0; + QScopedPointer<QFontEngine> fe; if (fp) { if (fp->rawMode) { - fe = loadEngine(script, fp, request, 0, 0, 0, 0 - ); + fe.reset(loadEngine(script, fp, request, 0, 0, 0, 0)); // if we fail to load the rawmode font, use a 12pixel box engine instead - if (! fe) fe = new QFontEngineBox(12); - return fe; + if (fe.isNull()) + fe.reset(new QFontEngineBox(12)); + return fe.take(); } QFontCache::Key key(request, script); - fe = QFontCache::instance()->findEngine(key); - if (fe) - return fe; + fe.reset(QFontCache::instance()->findEngine(key)); + if (! fe.isNull()) + return fe.take(); } QString family_name, foundry_name; @@ -898,11 +800,11 @@ QFontDatabase::findFont(int script, const QFontPrivate *fp, script, request.weight, request.style, request.stretch, request.pixelSize, pitch); if (qt_enable_test_font && request.family == QLatin1String("__Qt__Box__Engine__")) { - fe = new QTestFontEngine(request.pixelSize); + fe.reset(new QTestFontEngine(request.pixelSize)); fe->fontDef = request; } - if (!fe) + if (fe.isNull()) { QtFontDesc desc; match(script, request, family_name, foundry_name, force_encoding_id, &desc); @@ -923,16 +825,28 @@ QFontDatabase::findFont(int script, const QFontPrivate *fp, 'p', 0 ); - fe = loadEngine(script, fp, request, desc.family, desc.foundry, desc.style, desc.size - ); + fe.reset(loadEngine(script, fp, request, desc.family, desc.foundry, desc.style, desc.size + )); } else { FM_DEBUG(" NO MATCH FOUND\n"); } - if (fe) + if (! fe.isNull()) initFontDef(desc, request, &fe->fontDef); } - if (fe) { +#ifndef QT_NO_FREETYPE + if (! fe.isNull()) { + if (scriptRequiresOpenType(script) && fe->type() == QFontEngine::Freetype) { + HB_Face hbFace = static_cast<QFontEngineFT *>(fe.data())->harfbuzzFace(); + if (!hbFace || !hbFace->supported_scripts[script]) { + FM_DEBUG(" OpenType support missing for script\n"); + fe.reset(0); + } + } + } +#endif + + if (! fe.isNull()) { if (fp) { QFontDef def = request; if (def.family.isEmpty()) { @@ -940,32 +854,21 @@ QFontDatabase::findFont(int script, const QFontPrivate *fp, def.family = def.family.left(def.family.indexOf(QLatin1Char(','))); } QFontCache::Key key(def, script); - QFontCache::instance()->insertEngine(key, fe); - } - -#ifndef QT_NO_FREETYPE - if (scriptRequiresOpenType(script) && fe->type() == QFontEngine::Freetype) { - HB_Face hbFace = static_cast<QFontEngineFT *>(fe)->harfbuzzFace(); - if (!hbFace || !hbFace->supported_scripts[script]) { - FM_DEBUG(" OpenType support missing for script\n"); - delete fe; - fe = 0; - } + QFontCache::instance()->insertEngine(key, fe.data()); } -#endif } - if (!fe) { + if (fe.isNull()) { if (!request.family.isEmpty()) return 0; FM_DEBUG("returning box engine"); - fe = new QFontEngineBox(request.pixelSize); + fe.reset(new QFontEngineBox(request.pixelSize)); if (fp) { QFontCache::Key key(request, script); - QFontCache::instance()->insertEngine(key, fe); + QFontCache::instance()->insertEngine(key, fe.data()); } } @@ -975,7 +878,7 @@ QFontDatabase::findFont(int script, const QFontPrivate *fp, fe->fontDef.pointSize = request.pointSize; } - return fe; + return fe.take(); } void QFontDatabase::load(const QFontPrivate *d, int script) @@ -996,7 +899,13 @@ void QFontDatabase::load(const QFontPrivate *d, int script) if (!d->engineData) { // create a new one d->engineData = new QFontEngineData; - QFontCache::instance()->insertEngineData(key, d->engineData); + QT_TRY { + QFontCache::instance()->insertEngineData(key, d->engineData); + } QT_CATCH(...) { + delete d->engineData; + d->engineData = 0; + QT_RETHROW; + } } else { d->engineData->ref.ref(); } @@ -1005,8 +914,6 @@ void QFontDatabase::load(const QFontPrivate *d, int script) // the cached engineData could have already loaded the engine we want if (d->engineData->engines[script]) return; - // load the font - QFontEngine *engine = 0; // double scale = 1.0; // ### TODO: fix the scale calculations // list of families to try @@ -1038,20 +945,15 @@ void QFontDatabase::load(const QFontPrivate *d, int script) // null family means find the first font matching the specified script family_list << QString(); + // load the font + QFontEngine *engine = 0; QStringList::ConstIterator it = family_list.constBegin(), end = family_list.constEnd(); - for (; ! engine && it != end; ++it) { + for (; !engine && it != end; ++it) { req.family = *it; engine = QFontDatabase::findFont(script, d, req); - if (engine) { - if (engine->type() != QFontEngine::Box) - break; - - if (! req.family.isEmpty()) - engine = 0; - - continue; - } + if (engine && (engine->type()==QFontEngine::Box) && !req.family.isEmpty()) + engine = 0; } engine->ref.ref(); diff --git a/src/gui/text/qfontdatabase_s60.cpp b/src/gui/text/qfontdatabase_s60.cpp new file mode 100644 index 0000000..b93b4d7 --- /dev/null +++ b/src/gui/text/qfontdatabase_s60.cpp @@ -0,0 +1,428 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtGui of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.1, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include <private/qapplication_p.h> +#include "qdir.h" +#include "qfont_p.h" +#include "qfontengine_s60_p.h" +#include "qabstractfileengine.h" +#include "qdesktopservices.h" +#include "qt_s60_p.h" +#include "qendian.h" +#include <private/qwindowsurface_s60_p.h> +#include <private/qcore_symbian_p.h> +#if defined(QT_NO_FREETYPE) +#include <OPENFONT.H> +#endif + +QT_BEGIN_NAMESPACE + +QFileInfoList alternativeFilePaths(const QString &path, const QStringList &nameFilters, + QDir::Filters filters = QDir::NoFilter, QDir::SortFlags sort = QDir::NoSort, + bool uniqueFileNames = true) +{ + QFileInfoList result; + + // Prepare a 'soft to hard' drive list: W:, X: ... A:, Z: + QStringList driveStrings; + foreach (const QFileInfo &drive, QDir::drives()) + driveStrings.append(drive.absolutePath()); + driveStrings.sort(); + const QString zDriveString("Z:/"); + driveStrings.removeAll(zDriveString); + driveStrings.prepend(zDriveString); + + QStringList uniqueFileNameList; + for (int i = driveStrings.count() - 1; i >= 0; --i) { + const QDir dirOnDrive(driveStrings.at(i) + path); + const QFileInfoList entriesOnDrive = dirOnDrive.entryInfoList(nameFilters, filters, sort); + if (uniqueFileNames) { + foreach(const QFileInfo &entry, entriesOnDrive) { + if (!uniqueFileNameList.contains(entry.fileName())) { + uniqueFileNameList.append(entry.fileName()); + result.append(entry); + } + } + } else { + result.append(entriesOnDrive); + } + } + return result; +} + +#if defined(QT_NO_FREETYPE) +class QFontDatabaseS60StoreImplementation : public QFontDatabaseS60Store +{ +public: + QFontDatabaseS60StoreImplementation(); + ~QFontDatabaseS60StoreImplementation(); + + const QFontEngineS60Extensions *extension(const QString &typeface) const; + +private: + RHeap* m_heap; + CFontStore *m_store; + COpenFontRasterizer *m_rasterizer; + mutable QHash<QString, const QFontEngineS60Extensions *> m_extensions; +}; + +QFontDatabaseS60StoreImplementation::QFontDatabaseS60StoreImplementation() +{ + m_heap = User::ChunkHeap(NULL, 0x1000, 0x100000); + QT_TRAP_THROWING( + m_store = CFontStore::NewL(m_heap); + m_rasterizer = COpenFontRasterizer::NewL(TUid::Uid(0x101F7F5E)); + CleanupStack::PushL(m_rasterizer); + m_store->InstallRasterizerL(m_rasterizer); + CleanupStack::Pop(m_rasterizer);); + + QStringList filters; + filters.append(QString::fromLatin1("*.ttf")); + filters.append(QString::fromLatin1("*.ccc")); + const QFileInfoList fontFiles = alternativeFilePaths(QString::fromLatin1("resource\\Fonts"), filters); + foreach (const QFileInfo &fontFileInfo, fontFiles) { + const QString fontFile = QDir::toNativeSeparators(fontFileInfo.absoluteFilePath()); + TPtrC fontFilePtr(qt_QString2TPtrC(fontFile)); + QT_TRAP_THROWING(m_store->AddFileL(fontFilePtr)); + } +} +QFontDatabaseS60StoreImplementation::~QFontDatabaseS60StoreImplementation() +{ + typedef QHash<QString, const QFontEngineS60Extensions *>::iterator iterator; + for (iterator p = m_extensions.begin(); p != m_extensions.end(); ++p) { + m_store->ReleaseFont((*p)->fontOwner()); + delete *p; + } + + delete m_store; + m_heap->Close(); +} + +const QFontEngineS60Extensions *QFontDatabaseS60StoreImplementation::extension(const QString &typeface) const +{ + if (!m_extensions.contains(typeface)) { + CFont* font = NULL; + TFontSpec spec(qt_QString2TPtrC(typeface), 1); + spec.iHeight = 1; + const TInt err = m_store->GetNearestFontToDesignHeightInPixels(font, spec); + Q_ASSERT(err == KErrNone && font); + CBitmapFont *bitmapFont = static_cast<CBitmapFont*>(font); + m_extensions.insert(typeface, new QFontEngineS60Extensions(font, bitmapFont->OpenFont())); + } + return m_extensions.value(typeface); +} +#else +class QFontEngineFTS60 : public QFontEngineFT +{ +public: + QFontEngineFTS60(const QFontDef &fd); +}; + +QFontEngineFTS60::QFontEngineFTS60(const QFontDef &fd) + : QFontEngineFT(fd) +{ + default_hint_style = HintFull; +} +#endif // defined(QT_NO_FREETYPE) + +/* + QFontEngineS60::pixelsToPoints, QFontEngineS60::pointsToPixels, QFontEngineMultiS60::QFontEngineMultiS60 + and QFontEngineMultiS60::QFontEngineMultiS60 should be in qfontengine_s60.cpp. But since also the + Freetype based font rendering need them, they are here. +*/ +qreal QFontEngineS60::pixelsToPoints(qreal pixels, Qt::Orientation orientation) +{ + return (orientation == Qt::Horizontal? + S60->screenDevice()->HorizontalPixelsToTwips(pixels) + :S60->screenDevice()->VerticalPixelsToTwips(pixels)) / KTwipsPerPoint; +} + +qreal QFontEngineS60::pointsToPixels(qreal points, Qt::Orientation orientation) +{ + const int twips = points * KTwipsPerPoint; + return orientation == Qt::Horizontal? + S60->screenDevice()->HorizontalTwipsToPixels(twips) + :S60->screenDevice()->VerticalTwipsToPixels(twips); +} + +QFontEngineMultiS60::QFontEngineMultiS60(QFontEngine *first, int script, const QStringList &fallbackFamilies) + : QFontEngineMulti(fallbackFamilies.size() + 1) + , m_script(script) + , m_fallbackFamilies(fallbackFamilies) +{ + engines[0] = first; + first->ref.ref(); + fontDef = engines[0]->fontDef; +} + +void QFontEngineMultiS60::loadEngine(int at) +{ + Q_ASSERT(at < engines.size()); + Q_ASSERT(engines.at(at) == 0); + + QFontDef request = fontDef; + request.styleStrategy |= QFont::NoFontMerging; + request.family = m_fallbackFamilies.at(at-1); + engines[at] = QFontDatabase::findFont(m_script, + /*fontprivate*/0, + request); + Q_ASSERT(engines[at]); +} + +static void initializeDb() +{ + QFontDatabasePrivate *db = privateDb(); + if(!db || db->count) + return; + +#if defined(QT_NO_FREETYPE) + if (!db->s60Store) + db->s60Store = new QFontDatabaseS60StoreImplementation; + + QS60WindowSurface::unlockBitmapHeap(); + const int numTypeFaces = QS60Data::screenDevice()->NumTypefaces(); + const QFontDatabaseS60StoreImplementation *store = dynamic_cast<const QFontDatabaseS60StoreImplementation*>(db->s60Store); + Q_ASSERT(store); + for (int i = 0; i < numTypeFaces; i++) { + TTypefaceSupport typefaceSupport; + QS60Data::screenDevice()->TypefaceSupport(typefaceSupport, i); + CFont *font; // We have to get a font instance in order to know all the details + TFontSpec fontSpec(typefaceSupport.iTypeface.iName, 11); + qt_symbian_throwIfError(QS60Data::screenDevice()->GetNearestFontInPixels(font, fontSpec)); + if (font->TypeUid() == KCFbsFontUid) { + TOpenFontFaceAttrib faceAttrib; + const CFbsFont *cfbsFont = dynamic_cast<const CFbsFont *>(font); + Q_ASSERT(cfbsFont); + cfbsFont->GetFaceAttrib(faceAttrib); + + QtFontStyle::Key styleKey; + styleKey.style = faceAttrib.IsItalic()?QFont::StyleItalic:QFont::StyleNormal; + styleKey.weight = faceAttrib.IsBold()?QFont::Bold:QFont::Normal; + + QString familyName((const QChar *)typefaceSupport.iTypeface.iName.Ptr(), typefaceSupport.iTypeface.iName.Length()); + QtFontFamily *family = db->family(familyName, true); + family->fixedPitch = faceAttrib.IsMonoWidth(); + QtFontFoundry *foundry = family->foundry(QString(), true); + QtFontStyle *style = foundry->style(styleKey, true); + style->smoothScalable = typefaceSupport.iIsScalable; + style->pixelSize(0, true); + + const QFontEngineS60Extensions *extension = store->extension(familyName); + const QByteArray os2Table = extension->getSfntTable(MAKE_TAG('O', 'S', '/', '2')); + const unsigned char* data = reinterpret_cast<const unsigned char*>(os2Table.constData()); + const unsigned char* ulUnicodeRange = data + 42; + quint32 unicodeRange[4] = { + qFromBigEndian<quint32>(ulUnicodeRange), + qFromBigEndian<quint32>(ulUnicodeRange + 4), + qFromBigEndian<quint32>(ulUnicodeRange + 8), + qFromBigEndian<quint32>(ulUnicodeRange + 12) + }; + const unsigned char* ulCodePageRange = data + 78; + quint32 codePageRange[2] = { + qFromBigEndian<quint32>(ulCodePageRange), + qFromBigEndian<quint32>(ulCodePageRange + 4) + }; + const QList<QFontDatabase::WritingSystem> writingSystems = + determineWritingSystemsFromTrueTypeBits(unicodeRange, codePageRange); + foreach (const QFontDatabase::WritingSystem system, writingSystems) + family->writingSystems[system] = QtFontFamily::Supported; + } + QS60Data::screenDevice()->ReleaseFont(font); + } + QS60WindowSurface::lockBitmapHeap(); +#else // defined(QT_NO_FREETYPE) + QDir dir(QDesktopServices::storageLocation(QDesktopServices::FontsLocation)); + dir.setNameFilters(QStringList() << QLatin1String("*.ttf") + << QLatin1String("*.ttc") << QLatin1String("*.pfa") + << QLatin1String("*.pfb")); + for (int i = 0; i < int(dir.count()); ++i) { + const QByteArray file = QFile::encodeName(dir.absoluteFilePath(dir[i])); + db->addTTFile(file); + } +#endif // defined(QT_NO_FREETYPE) +} + +static inline void load(const QString &family = QString(), int script = -1) +{ + Q_UNUSED(family) + Q_UNUSED(script) + initializeDb(); +} + +static void registerFont(QFontDatabasePrivate::ApplicationFont *fnt) +{ + Q_UNUSED(fnt); +} + +bool QFontDatabase::removeApplicationFont(int handle) +{ + Q_UNUSED(handle); + return false; +} + +bool QFontDatabase::supportsThreadedFontRendering() +{ + return false; +} + +static +QFontDef cleanedFontDef(const QFontDef &req) +{ + QFontDef result = req; + if (result.pixelSize <= 0) { + result.pixelSize = QFontEngineS60::pointsToPixels(qMax(qreal(1.0), result.pointSize)); + result.pointSize = 0; + } + return result; +} + +QFontEngine *QFontDatabase::findFont(int script, const QFontPrivate *, const QFontDef &req) +{ + const QFontCache::Key key(cleanedFontDef(req), script); + + if (!privateDb()->count) + initializeDb(); + + QFontEngine *fe = QFontCache::instance()->findEngine(key); + if (!fe) { + // Making sure that fe->fontDef.family will be an existing font. + initializeDb(); + QFontDatabasePrivate *db = privateDb(); + QtFontDesc desc; + QList<int> blacklistedFamilies; + match(script, req, req.family, QString(), -1, &desc, blacklistedFamilies); + if (!desc.family) // falling back to application font + desc.family = db->family(QApplication::font().defaultFamily()); + Q_ASSERT(desc.family); + + // Making sure that desc.family supports the requested script + QtFontDesc mappedDesc; + bool supportsScript = false; + do { + match(script, req, QString(), QString(), -1, &mappedDesc, blacklistedFamilies); + if (mappedDesc.family == desc.family) { + supportsScript = true; + break; + } + blacklistedFamilies.append(mappedDesc.familyIndex); + } while (mappedDesc.family); + if (!supportsScript) { + blacklistedFamilies.clear(); + match(script, req, QString(), QString(), -1, &mappedDesc, blacklistedFamilies); + if (mappedDesc.family) + desc = mappedDesc; + } + + const QString fontFamily = desc.family->name; + QFontDef request = req; + request.family = fontFamily; +#if defined(QT_NO_FREETYPE) + const QFontDatabaseS60StoreImplementation *store = dynamic_cast<const QFontDatabaseS60StoreImplementation*>(db->s60Store); + Q_ASSERT(store); + const QFontEngineS60Extensions *extension = store->extension(fontFamily); + fe = new QFontEngineS60(request, extension); +#else + QFontEngine::FaceId faceId; + const QtFontFamily * const reqQtFontFamily = db->family(fontFamily); + faceId.filename = reqQtFontFamily->fontFilename; + faceId.index = reqQtFontFamily->fontFileIndex; + + QFontEngineFTS60 *fte = new QFontEngineFTS60(cleanedFontDef(request)); + if (fte->init(faceId, true, QFontEngineFT::Format_A8)) + fe = fte; + else + delete fte; +#endif + + Q_ASSERT(fe); + if (script == QUnicodeTables::Common + && !(req.styleStrategy & QFont::NoFontMerging) + && !fe->symbol) { + + QStringList commonFonts; + for (int ws = 1; ws < QFontDatabase::WritingSystemsCount; ++ws) { + if (scriptForWritingSystem[ws] != script) + continue; + for (int i = 0; i < db->count; ++i) { + if (db->families[i]->writingSystems[ws] & QtFontFamily::Supported) + commonFonts.append(db->families[i]->name); + } + } + + // Hack: Prioritize .ccc fonts + const QString niceEastAsianFont(QLatin1String("Sans MT 936_S60")); + if (commonFonts.removeAll(niceEastAsianFont) > 0) + commonFonts.prepend(niceEastAsianFont); + + fe = new QFontEngineMultiS60(fe, script, commonFonts); + } + } + fe->ref.ref(); + QFontCache::instance()->insertEngine(key, fe); + return fe; +} + +void QFontDatabase::load(const QFontPrivate *d, int script) +{ + QFontEngine *fe = 0; + QFontDef req = d->request; + + if (!d->engineData) { + const QFontCache::Key key(cleanedFontDef(req), script); + getEngineData(d, key); + } + + // the cached engineData could have already loaded the engine we want + if (d->engineData->engines[script]) + fe = d->engineData->engines[script]; + + if (!fe) { + if (qt_enable_test_font && req.family == QLatin1String("__Qt__Box__Engine__")) { + fe = new QTestFontEngine(req.pixelSize); + fe->fontDef = req; + } else { + fe = findFont(script, d, req); + } + d->engineData->engines[script] = fe; + } +} + +QT_END_NAMESPACE diff --git a/src/gui/text/qfontdatabase_win.cpp b/src/gui/text/qfontdatabase_win.cpp index cf6f6d7..76bd3f8 100644 --- a/src/gui/text/qfontdatabase_win.cpp +++ b/src/gui/text/qfontdatabase_win.cpp @@ -1,7 +1,6 @@ /**************************************************************************** ** ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** ** This file is part of the QtGui module of the Qt Toolkit. @@ -21,9 +20,10 @@ ** ensure the GNU Lesser General Public License version 2.1 requirements ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. ** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.1, included in the file LGPL_EXCEPTION.txt in this +** package. ** ** If you have questions regarding the use of this file, please contact ** Nokia at qt-info@nokia.com. @@ -195,21 +195,12 @@ static QString getEnglishName(const QString &familyName) QString i18n_name; HDC hdc = GetDC( 0 ); - HFONT hfont; - QT_WA( { - LOGFONTW lf; - memset( &lf, 0, sizeof( LOGFONTW ) ); - memcpy( lf.lfFaceName, familyName.utf16(), qMin(LF_FACESIZE, familyName.length())*sizeof(QChar) ); - lf.lfCharSet = DEFAULT_CHARSET; - hfont = CreateFontIndirectW( &lf ); - }, { - LOGFONTA lf; - memset( &lf, 0, sizeof( LOGFONTA ) ); - QByteArray lfam = familyName.toLocal8Bit(); - memcpy( lf.lfFaceName, lfam, qMin(LF_FACESIZE, lfam.size()) ); - lf.lfCharSet = DEFAULT_CHARSET; - hfont = CreateFontIndirectA( &lf ); - } ); + LOGFONT lf; + memset(&lf, 0, sizeof(LOGFONT)); + memcpy(lf.lfFaceName, familyName.utf16(), qMin(LF_FACESIZE, familyName.length()) * sizeof(wchar_t)); + lf.lfCharSet = DEFAULT_CHARSET; + HFONT hfont = CreateFontIndirect(&lf); + if(!hfont) { ReleaseDC(0, hdc); return QString(); @@ -245,32 +236,6 @@ error: return i18n_name; } -static void getFontSignature(const QString &familyName, - NEWTEXTMETRICEX *textmetric, - FONTSIGNATURE *signature) -{ - QT_WA({ - Q_UNUSED(familyName); - *signature = textmetric->ntmFontSig; - }, { - // the textmetric structure we get from EnumFontFamiliesEx on Win9x has - // a FONTSIGNATURE, but that one is uninitialized and doesn't work. Have to go - // the hard way and load the font to find out. - HDC hdc = GetDC(0); - LOGFONTA lf; - memset(&lf, 0, sizeof(LOGFONTA)); - QByteArray lfam = familyName.toLocal8Bit(); - memcpy(lf.lfFaceName, lfam.data(), qMin(LF_FACESIZE, lfam.length())); - lf.lfCharSet = DEFAULT_CHARSET; - HFONT hfont = CreateFontIndirectA(&lf); - HGDIOBJ oldobj = SelectObject(hdc, hfont); - GetTextCharsetInfo(hdc, signature, 0); - SelectObject(hdc, oldobj); - DeleteObject(hfont); - ReleaseDC(0, hdc); - }); -} - static void addFontToDatabase(QString familyName, const QString &scriptName, TEXTMETRIC *textmetric, @@ -288,26 +253,17 @@ void addFontToDatabase(QString familyName, const QString &scriptName, bool scalable; int size; -// QString escript = QString::fromUtf16((ushort *)f->elfScript); +// QString escript = QString::fromWCharArray(f->elfScript); // qDebug("script=%s", escript.latin1()); - QT_WA({ - NEWTEXTMETRIC *tm = (NEWTEXTMETRIC *)textmetric; - fixed = !(tm->tmPitchAndFamily & TMPF_FIXED_PITCH); - ttf = (tm->tmPitchAndFamily & TMPF_TRUETYPE); - scalable = tm->tmPitchAndFamily & (TMPF_VECTOR|TMPF_TRUETYPE); - size = scalable ? SMOOTH_SCALABLE : tm->tmHeight; - italic = tm->tmItalic; - weight = tm->tmWeight; - } , { - NEWTEXTMETRICA *tm = (NEWTEXTMETRICA *)textmetric; - fixed = !(tm->tmPitchAndFamily & TMPF_FIXED_PITCH); - ttf = (tm->tmPitchAndFamily & TMPF_TRUETYPE); - scalable = tm->tmPitchAndFamily & (TMPF_VECTOR|TMPF_TRUETYPE); - size = scalable ? SMOOTH_SCALABLE : tm->tmHeight; - italic = tm->tmItalic; - weight = tm->tmWeight; - }); + NEWTEXTMETRIC *tm = (NEWTEXTMETRIC *)textmetric; + fixed = !(tm->tmPitchAndFamily & TMPF_FIXED_PITCH); + ttf = (tm->tmPitchAndFamily & TMPF_TRUETYPE); + scalable = tm->tmPitchAndFamily & (TMPF_VECTOR|TMPF_TRUETYPE); + size = scalable ? SMOOTH_SCALABLE : tm->tmHeight; + italic = tm->tmItalic; + weight = tm->tmWeight; + // the "@family" fonts are just the same as "family". Ignore them. if (familyName[0] != QLatin1Char('@') && !familyName.startsWith(QLatin1String("WST_"))) { QtFontStyle::Key styleKey; @@ -364,7 +320,7 @@ void addFontToDatabase(QString familyName, const QString &scriptName, signature->fsUsb[0], signature->fsUsb[1], signature->fsUsb[2], signature->fsUsb[3] }; -#ifdef Q_OS_WINCE +#ifdef Q_WS_WINCE if (signature->fsUsb[0] == 0) { // If the unicode ranges bit mask is zero then // EnumFontFamiliesEx failed to determine it properly. @@ -420,18 +376,10 @@ static int CALLBACK storeFont(ENUMLOGFONTEX* f, NEWTEXTMETRICEX *textmetric, int type, LPARAM /*p*/) { - QString familyName; - QT_WA({ - familyName = QString::fromUtf16((ushort*)f->elfLogFont.lfFaceName); - },{ - ENUMLOGFONTEXA *fa = (ENUMLOGFONTEXA *)f; - familyName = QString::fromLocal8Bit(fa->elfLogFont.lfFaceName); - }); - QString script = QT_WA_INLINE(QString::fromUtf16((const ushort *)f->elfScript), - QString::fromLocal8Bit((const char *)((ENUMLOGFONTEXA *)f)->elfScript)); - - FONTSIGNATURE signature; - getFontSignature(familyName, textmetric, &signature); + QString familyName = QString::fromWCharArray(f->elfLogFont.lfFaceName); + QString script = QString::fromWCharArray(f->elfScript); + + FONTSIGNATURE signature = textmetric->ntmFontSig; // NEWTEXTMETRICEX is a NEWTEXTMETRIC, which according to the documentation is // identical to a TEXTMETRIC except for the last four members, which we don't use @@ -459,33 +407,17 @@ void populate_database(const QString& fam) HDC dummy = GetDC(0); - QT_WA({ - LOGFONT lf; - lf.lfCharSet = DEFAULT_CHARSET; - if (fam.isNull()) { - lf.lfFaceName[0] = 0; - } else { - memcpy(lf.lfFaceName, fam.utf16(), sizeof(TCHAR)*qMin(fam.length()+1,32)); // 32 = Windows hard-coded - } - lf.lfPitchAndFamily = 0; - - EnumFontFamiliesEx(dummy, &lf, - (FONTENUMPROC)storeFont, (LPARAM)privateDb(), 0); - } , { - LOGFONTA lf; - lf.lfCharSet = DEFAULT_CHARSET; - if (fam.isNull()) { - lf.lfFaceName[0] = 0; - } else { - QByteArray lname = fam.toLocal8Bit(); - memcpy(lf.lfFaceName,lname.data(), - qMin(lname.length()+1,32)); // 32 = Windows hard-coded - } - lf.lfPitchAndFamily = 0; + LOGFONT lf; + lf.lfCharSet = DEFAULT_CHARSET; + if (fam.isNull()) { + lf.lfFaceName[0] = 0; + } else { + memcpy(lf.lfFaceName, fam.utf16(), sizeof(wchar_t) * qMin(fam.length() + 1, 32)); // 32 = Windows hard-coded + } + lf.lfPitchAndFamily = 0; - EnumFontFamiliesExA(dummy, &lf, - (FONTENUMPROCA)storeFont, (LPARAM)privateDb(), 0); - }); + EnumFontFamiliesEx(dummy, &lf, + (FONTENUMPROC)storeFont, (LPARAM)privateDb(), 0); ReleaseDC(0, dummy); @@ -496,21 +428,11 @@ void populate_database(const QString& fam) for (int j = 0; j < fnt.families.count(); ++j) { const QString familyName = fnt.families.at(j); HDC hdc = GetDC(0); - HFONT hfont; - QT_WA({ - LOGFONTW lf; - memset(&lf, 0, sizeof(LOGFONTW)); - memcpy(lf.lfFaceName, familyName.utf16(), qMin(LF_FACESIZE, familyName.size())); - lf.lfCharSet = DEFAULT_CHARSET; - hfont = CreateFontIndirectW(&lf); - } , { - LOGFONTA lf; - memset(&lf, 0, sizeof(LOGFONTA)); - QByteArray lfam = familyName.toLocal8Bit(); - memcpy(lf.lfFaceName, lfam.data(), qMin(LF_FACESIZE, lfam.length())); - lf.lfCharSet = DEFAULT_CHARSET; - hfont = CreateFontIndirectA(&lf); - }); + LOGFONT lf; + memset(&lf, 0, sizeof(LOGFONT)); + memcpy(lf.lfFaceName, familyName.utf16(), sizeof(wchar_t) * qMin(LF_FACESIZE, familyName.size())); + lf.lfCharSet = DEFAULT_CHARSET; + HFONT hfont = CreateFontIndirect(&lf); HGDIOBJ oldobj = SelectObject(hdc, hfont); TEXTMETRIC textMetrics; @@ -598,17 +520,10 @@ static void initFontInfo(QFontEngineWin *fe, const QFontDef &request, const QFon HDC dc = ((request.styleStrategy & QFont::PreferDevice) && fp->hdc) ? fp->hdc : shared_dc(); SelectObject(dc, fe->hfont); - QT_WA({ - TCHAR n[64]; - GetTextFaceW(dc, 64, n); - fe->fontDef.family = QString::fromUtf16((ushort*)n); - fe->fontDef.fixedPitch = !(fe->tm.w.tmPitchAndFamily & TMPF_FIXED_PITCH); - } , { - char an[64]; - GetTextFaceA(dc, 64, an); - fe->fontDef.family = QString::fromLocal8Bit(an); - fe->fontDef.fixedPitch = !(fe->tm.a.tmPitchAndFamily & TMPF_FIXED_PITCH); - }); + wchar_t n[64]; + GetTextFace(dc, 64, n); + fe->fontDef.family = QString::fromWCharArray(n); + fe->fontDef.fixedPitch = !(fe->tm.tmPitchAndFamily & TMPF_FIXED_PITCH); if (fe->fontDef.pointSize < 0) { fe->fontDef.pointSize = fe->fontDef.pixelSize * 72. / fp->dpi; } else if (fe->fontDef.pixelSize == -1) { @@ -704,18 +619,13 @@ QFontEngine *loadEngine(int script, const QFontPrivate *fp, const QFontDef &requ HFONT hfont = 0; if (fp->rawMode) { // will choose a stock font - int f, deffnt; - // ### why different? - if ((QSysInfo::WindowsVersion & QSysInfo::WV_NT_based) || QSysInfo::WindowsVersion == QSysInfo::WV_32s) - deffnt = SYSTEM_FONT; - else - deffnt = DEFAULT_GUI_FONT; + int f, deffnt = SYSTEM_FONT; QString fam = desc->family->name.toLower(); if (fam == QLatin1String("default")) f = deffnt; else if (fam == QLatin1String("system")) f = SYSTEM_FONT; -#ifndef Q_OS_WINCE +#ifndef Q_WS_WINCE else if (fam == QLatin1String("system_fixed")) f = SYSTEM_FIXED_FONT; else if (fam == QLatin1String("ansi_fixed")) @@ -774,15 +684,11 @@ QFontEngine *loadEngine(int script, const QFontPrivate *fp, const QFontDef &requ int strat = OUT_DEFAULT_PRECIS; if (request.styleStrategy & QFont::PreferBitmap) { strat = OUT_RASTER_PRECIS; -#ifndef Q_OS_WINCE +#ifndef Q_WS_WINCE } else if (request.styleStrategy & QFont::PreferDevice) { strat = OUT_DEVICE_PRECIS; } else if (request.styleStrategy & QFont::PreferOutline) { - QT_WA({ - strat = OUT_OUTLINE_PRECIS; - } , { - strat = OUT_TT_PRECIS; - }); + strat = OUT_OUTLINE_PRECIS; } else if (request.styleStrategy & QFont::ForceOutline) { strat = OUT_TT_ONLY_PRECIS; #endif @@ -794,14 +700,14 @@ QFontEngine *loadEngine(int script, const QFontPrivate *fp, const QFontDef &requ if (request.styleStrategy & QFont::PreferMatch) qual = DRAFT_QUALITY; -#ifndef Q_OS_WINCE +#ifndef Q_WS_WINCE else if (request.styleStrategy & QFont::PreferQuality) qual = PROOF_QUALITY; #endif if (request.styleStrategy & QFont::PreferAntialias) { if (QSysInfo::WindowsVersion >= QSysInfo::WV_XP) { - qual = 5; // == CLEARTYPE_QUALITY; + qual = CLEARTYPE_QUALITY; preferClearTypeAA = true; } else { qual = ANTIALIASED_QUALITY; @@ -827,16 +733,8 @@ QFontEngine *loadEngine(int script, const QFontPrivate *fp, const QFontDef &requ if (fam == QLatin1String("Courier") && !(request.styleStrategy & QFont::PreferBitmap)) fam = QLatin1String("Courier New"); - QT_WA({ - memcpy(lf.lfFaceName, fam.utf16(), sizeof(TCHAR)*qMin(fam.length()+1,32)); // 32 = Windows hard-coded - hfont = CreateFontIndirect(&lf); - } , { - // LOGFONTA and LOGFONTW are binary compatible - QByteArray lname = fam.toLocal8Bit(); - memcpy(lf.lfFaceName,lname.data(), - qMin(lname.length()+1,32)); // 32 = Windows hard-coded - hfont = CreateFontIndirectA((LOGFONTA*)&lf); - }); + memcpy(lf.lfFaceName, fam.utf16(), sizeof(wchar_t) * qMin(fam.length() + 1, 32)); // 32 = Windows hard-coded + hfont = CreateFontIndirect(&lf); if (!hfont) qErrnoWarning("QFontEngine::loadEngine: CreateFontIndirect failed"); @@ -845,17 +743,12 @@ QFontEngine *loadEngine(int script, const QFontPrivate *fp, const QFontDef &requ int avWidth = 0; BOOL res; HGDIOBJ oldObj = SelectObject(hdc, hfont); - QT_WA({ - TEXTMETRICW tm; - res = GetTextMetricsW(hdc, &tm); - avWidth = tm.tmAveCharWidth; - ttf = tm.tmPitchAndFamily & TMPF_TRUETYPE; - } , { - TEXTMETRICA tm; - res = GetTextMetricsA(hdc, &tm); - avWidth = tm.tmAveCharWidth; - ttf = tm.tmPitchAndFamily & TMPF_TRUETYPE; - }); + + TEXTMETRIC tm; + res = GetTextMetrics(hdc, &tm); + avWidth = tm.tmAveCharWidth; + ttf = tm.tmPitchAndFamily & TMPF_TRUETYPE; + SelectObject(hdc, oldObj); if (hfont && (!ttf || request.stretch != 100)) { @@ -863,16 +756,12 @@ QFontEngine *loadEngine(int script, const QFontPrivate *fp, const QFontDef &requ if (!res) qErrnoWarning("QFontEngine::loadEngine: GetTextMetrics failed"); lf.lfWidth = avWidth * request.stretch/100; - QT_WA({ - hfont = CreateFontIndirect(&lf); - } , { - hfont = CreateFontIndirectA((LOGFONTA*)&lf); - }); + hfont = CreateFontIndirect(&lf); if (!hfont) qErrnoWarning("QFontEngine::loadEngine: CreateFontIndirect with stretch failed"); } -#ifndef Q_OS_WINCE +#ifndef Q_WS_WINCE if (hfont == 0) { hfont = (HFONT)GetStockObject(ANSI_VAR_FONT); stockFont = true; @@ -969,12 +858,6 @@ static QFontEngine *loadWin(const QFontPrivate *d, int script, const QFontDef &r // list of families to try QStringList family_list = familyList(req); - if(QSysInfo::WindowsVersion & QSysInfo::WV_DOS_based && req.family.toLower() == QLatin1String("ms sans serif")) { - // small hack for Dos based machines to get the right font for non - // latin text when using the default font. - family_list << QLatin1String("Arial"); - } - const char *stylehint = styleHint(d->request); if (stylehint) family_list << QLatin1String(stylehint); @@ -1143,6 +1026,8 @@ static void getFamiliesAndSignatures(const QByteArray &fontData, QFontDatabasePr signature.fsCsb[0] = qFromBigEndian<quint32>(table + 78); signature.fsCsb[1] = qFromBigEndian<quint32>(table + 82); + } else { + memset(&signature, 0, sizeof(signature)); } appFont->signatures << signature; } @@ -1165,21 +1050,21 @@ static void registerFont(QFontDatabasePrivate::ApplicationFont *fnt) HANDLE handle = 0; { -#ifdef QT_NO_TEMPORARYFILE - TCHAR lpBuffer[MAX_PATH]; +#ifdef QT_NO_TEMPORARYFILE + wchar_t lpBuffer[MAX_PATH]; GetTempPath(MAX_PATH, lpBuffer); - QString s = QString::fromUtf16((const ushort *) lpBuffer); + QString s = QString::fromWCharArray(lpBuffer); QFile tempfile(s + QLatin1String("/font") + QString::number(GetTickCount()) + QLatin1String(".ttf")); if (!tempfile.open(QIODevice::ReadWrite)) #else QTemporaryFile tempfile(QLatin1String("XXXXXXXX.ttf")); if (!tempfile.open()) -#endif +#endif // QT_NO_TEMPORARYFILE return; if (tempfile.write(fnt->data) == -1) return; -#ifndef QT_NO_TEMPORARYFILE +#ifndef QT_NO_TEMPORARYFILE tempfile.setAutoRemove(false); #endif fnt->fileName = QFileInfo(tempfile.fileName()).absoluteFilePath(); @@ -1191,13 +1076,11 @@ static void registerFont(QFontDatabasePrivate::ApplicationFont *fnt) } #else DWORD dummy = 0; - HANDLE handle = ptrAddFontMemResourceEx((void *)fnt->data.constData(), - fnt->data.size(), - 0, - &dummy); + HANDLE handle = ptrAddFontMemResourceEx((void *)fnt->data.constData(), fnt->data.size(), 0, + &dummy); if (handle == 0) return; -#endif +#endif // Q_OS_WINCE fnt->handle = handle; fnt->data = QByteArray(); @@ -1219,12 +1102,10 @@ static void registerFont(QFontDatabasePrivate::ApplicationFont *fnt) // supported from 2000 on, so no need to deal with the *A variant PtrAddFontResourceExW ptrAddFontResourceExW = (PtrAddFontResourceExW)QLibrary::resolve(QLatin1String("gdi32"), "AddFontResourceExW"); - if (!ptrAddFontResourceExW) + if (!ptrAddFontResourceExW + || ptrAddFontResourceExW((wchar_t*)fnt->fileName.utf16(), FR_PRIVATE, 0) == 0) return; - - if (ptrAddFontResourceExW((LPCWSTR)fnt->fileName.utf16(), FR_PRIVATE, 0) == 0) - return; -#endif +#endif // Q_OS_WINCE fnt->memoryFont = false; } @@ -1250,12 +1131,10 @@ bool QFontDatabase::removeApplicationFont(int handle) #else PtrRemoveFontMemResourceEx ptrRemoveFontMemResourceEx = (PtrRemoveFontMemResourceEx)QLibrary::resolve(QLatin1String("gdi32"), "RemoveFontMemResourceEx"); - if (!ptrRemoveFontMemResourceEx) - return false; - - if (!ptrRemoveFontMemResourceEx(font.handle)) + if (!ptrRemoveFontMemResourceEx + || !ptrRemoveFontMemResourceEx(font.handle)) return false; -#endif +#endif // Q_OS_WINCE } else { #ifdef Q_OS_WINCE if (!RemoveFontResource((LPCWSTR)font.fileName.utf16())) @@ -1263,12 +1142,10 @@ bool QFontDatabase::removeApplicationFont(int handle) #else PtrRemoveFontResourceExW ptrRemoveFontResourceExW = (PtrRemoveFontResourceExW)QLibrary::resolve(QLatin1String("gdi32"), "RemoveFontResourceExW"); - if (!ptrRemoveFontResourceExW) + if (!ptrRemoveFontResourceExW + || !ptrRemoveFontResourceExW((LPCWSTR)font.fileName.utf16(), FR_PRIVATE, 0)) return false; - - if (!ptrRemoveFontResourceExW((LPCWSTR)font.fileName.utf16(), FR_PRIVATE, 0)) - return false; -#endif +#endif // Q_OS_WINCE } db->invalidate(); diff --git a/src/gui/text/qfontdatabase_x11.cpp b/src/gui/text/qfontdatabase_x11.cpp index af307fc..7e2c474 100644 --- a/src/gui/text/qfontdatabase_x11.cpp +++ b/src/gui/text/qfontdatabase_x11.cpp @@ -1,7 +1,6 @@ /**************************************************************************** ** ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** ** This file is part of the QtGui module of the Qt Toolkit. @@ -21,9 +20,10 @@ ** ensure the GNU Lesser General Public License version 2.1 requirements ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. ** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.1, included in the file LGPL_EXCEPTION.txt in this +** package. ** ** If you have questions regarding the use of this file, please contact ** Nokia at qt-info@nokia.com. @@ -392,7 +392,7 @@ int qt_mib_for_xlfd_encoding(const char *encoding) int id = qt_xlfd_encoding_id(encoding); if (id != -1) return xlfd_encoding[id].mib; return 0; -}; +} int qt_encoding_id_for_mib(int mib) { @@ -509,9 +509,9 @@ bool qt_fillFontDef(const QByteArray &xlfd, QFontDef *fd, int dpi, QtFontDesc *d fd->styleStrategy |= QFont::NoAntialias; fd->family = QString::fromLatin1(tokens[Family]); QString foundry = QString::fromLatin1(tokens[Foundry]); - if (! foundry.isEmpty() && foundry != QString::fromLatin1("*") && (!desc || desc->family->count > 1)) + if (! foundry.isEmpty() && foundry != QLatin1String("*") && (!desc || desc->family->count > 1)) fd->family += - QString::fromLatin1(" [") + foundry + QString::fromLatin1("]"); + QLatin1String(" [") + foundry + QLatin1Char(']'); if (qstrlen(tokens[AddStyle]) > 0) fd->addStyle = QString::fromLatin1(tokens[AddStyle]); @@ -1802,30 +1802,30 @@ QFontEngine *QFontDatabase::loadXlfd(int screen, int script, const QFontDef &req QByteArray xlfd("-"); xlfd += desc.foundry->name.isEmpty() ? QByteArray("*") : desc.foundry->name.toLatin1(); - xlfd += "-"; + xlfd += '-'; xlfd += desc.family->name.isEmpty() ? QByteArray("*") : desc.family->name.toLatin1(); - xlfd += "-"; + xlfd += '-'; xlfd += desc.style->weightName ? desc.style->weightName : "*"; - xlfd += "-"; + xlfd += '-'; xlfd += (desc.style->key.style == QFont::StyleItalic - ? "i" - : (desc.style->key.style == QFont::StyleOblique ? "o" : "r")); - xlfd += "-"; + ? 'i' + : (desc.style->key.style == QFont::StyleOblique ? 'o' : 'r')); + xlfd += '-'; xlfd += desc.style->setwidthName ? desc.style->setwidthName : "*"; // ### handle add-style xlfd += "-*-"; xlfd += QByteArray::number(px); - xlfd += "-"; + xlfd += '-'; xlfd += QByteArray::number(desc.encoding->xpoint); - xlfd += "-"; + xlfd += '-'; xlfd += QByteArray::number(desc.encoding->xres); - xlfd += "-"; + xlfd += '-'; xlfd += QByteArray::number(desc.encoding->yres); - xlfd += "-"; + xlfd += '-'; xlfd += desc.encoding->pitch; - xlfd += "-"; + xlfd += '-'; xlfd += QByteArray::number(desc.encoding->avgwidth); - xlfd += "-"; + xlfd += '-'; xlfd += xlfd_for_id(desc.encoding->encoding); FM_DEBUG(" using XLFD: %s\n", xlfd.data()); diff --git a/src/gui/text/qfontengine.cpp b/src/gui/text/qfontengine.cpp index 87c2a19..7a3b3e1 100644 --- a/src/gui/text/qfontengine.cpp +++ b/src/gui/text/qfontengine.cpp @@ -1,7 +1,6 @@ /**************************************************************************** ** ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** ** This file is part of the QtGui module of the Qt Toolkit. @@ -21,9 +20,10 @@ ** ensure the GNU Lesser General Public License version 2.1 requirements ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. ** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.1, included in the file LGPL_EXCEPTION.txt in this +** package. ** ** If you have questions regarding the use of this file, please contact ** Nokia at qt-info@nokia.com. @@ -70,12 +70,6 @@ static inline bool qtransform_equals_no_translate(const QTransform &a, const QTr } } - - -QFontEngineGlyphCache::~QFontEngineGlyphCache() -{ -} - // Harfbuzz helper functions static HB_Bool hb_stringToGlyphs(HB_Font font, const HB_UChar16 *string, hb_uint32 length, HB_Glyph *glyphs, hb_uint32 *numGlyphs, HB_Bool rightToLeft) @@ -191,18 +185,20 @@ QFontEngine::QFontEngine() QFontEngine::~QFontEngine() { - for (GlyphPointerHash::iterator it = m_glyphPointerHash.begin(), end = m_glyphPointerHash.end(); - it != end; ++it) { - for (QList<QFontEngineGlyphCache*>::iterator it2 = it.value().begin(), end2 = it.value().end(); - it2 != end2; ++it2) - delete *it2; + for (GlyphPointerHash::const_iterator it = m_glyphPointerHash.constBegin(), + end = m_glyphPointerHash.constEnd(); it != end; ++it) { + for (QList<QFontEngineGlyphCache*>::const_iterator it2 = it.value().constBegin(), + end2 = it.value().constEnd(); it2 != end2; ++it2) { + delete *it2; + } } m_glyphPointerHash.clear(); - for (GlyphIntHash::iterator it = m_glyphIntHash.begin(), end = m_glyphIntHash.end(); - it != end; ++it) { - for (QList<QFontEngineGlyphCache*>::iterator it2 = it.value().begin(), end2 = it.value().end(); - it2 != end2; ++it2) - delete *it2; + for (GlyphIntHash::const_iterator it = m_glyphIntHash.constBegin(), + end = m_glyphIntHash.constEnd(); it != end; ++it) { + for (QList<QFontEngineGlyphCache*>::const_iterator it2 = it.value().constBegin(), + end2 = it.value().constEnd(); it2 != end2; ++it2) { + delete *it2; + } } m_glyphIntHash.clear(); qHBFreeFace(hbFace); @@ -240,8 +236,10 @@ HB_Font QFontEngine::harfbuzzFont() const HB_Face QFontEngine::harfbuzzFace() const { - if (!hbFace) + if (!hbFace) { hbFace = qHBNewFace(const_cast<QFontEngine *>(this), hb_getSFntTable); + Q_CHECK_PTR(hbFace); + } return hbFace; } @@ -428,8 +426,7 @@ void QFontEngine::addOutlineToPath(qreal x, qreal y, const QGlyphLayout &glyphs, QVarLengthArray<QFixedPoint> positions; QVarLengthArray<glyph_t> positioned_glyphs; - QTransform matrix; - matrix.translate(x, y); + QTransform matrix = QTransform::fromTranslate(x, y); getGlyphPositions(glyphs, matrix, flags, positioned_glyphs, positions); addGlyphsToPath(positioned_glyphs.data(), positions.data(), positioned_glyphs.size(), path, flags); } @@ -819,7 +816,7 @@ QFontEngineGlyphCache *QFontEngine::glyphCache(QFontEngineGlyphCache::Type key, return 0; } -#if defined(Q_WS_WIN) || defined(Q_WS_X11) || defined(Q_WS_QWS) +#if defined(Q_WS_WIN) || defined(Q_WS_X11) || defined(Q_WS_QWS) || defined(Q_OS_SYMBIAN) static inline QFixed kerning(int left, int right, const QFontEngine::KernPair *pairs, int numPairs) { uint left_right = (left << 16) + right; @@ -915,7 +912,7 @@ void QFontEngine::loadKerningPairs(QFixed scalingFactor) end: qSort(kerning_pairs); // for (int i = 0; i < kerning_pairs.count(); ++i) -// qDebug() << "i" << i << "left_right" << hex << kerning_pairs.at(i).left_right; +// qDebug() << 'i' << i << "left_right" << hex << kerning_pairs.at(i).left_right; } #else @@ -1041,9 +1038,8 @@ quint32 QFontEngine::getTrueTypeGlyphIndex(const uchar *cmap, uint unicode) return 0; quint16 segCountX2 = qFromBigEndian<quint16>(cmap + 6); const unsigned char *ends = cmap + 14; - quint16 endIndex = 0; int i = 0; - for (; i < segCountX2/2 && (endIndex = qFromBigEndian<quint16>(ends + 2*i)) < unicode; i++) {} + for (; i < segCountX2/2 && qFromBigEndian<quint16>(ends + 2*i) < unicode; i++) {} const unsigned char *idx = ends + segCountX2 + 2 + 2*i; quint16 startIndex = qFromBigEndian<quint16>(idx); @@ -1110,6 +1106,18 @@ quint32 QFontEngine::getTrueTypeGlyphIndex(const uchar *cmap, uint unicode) return 0; } +Q_GLOBAL_STATIC_WITH_INITIALIZER(QVector<QRgb>, qt_grayPalette, { + x->resize(256); + QRgb *it = x->data(); + for (int i = 0; i < x->size(); ++i, ++it) + *it = 0xff000000 | i | (i<<8) | (i<<16); +}); + +const QVector<QRgb> &QFontEngine::grayPalette() +{ + return *qt_grayPalette(); +} + // ------------------------------------------------------------------ // The box font engine // ------------------------------------------------------------------ @@ -1157,8 +1165,7 @@ void QFontEngineBox::addOutlineToPath(qreal x, qreal y, const QGlyphLayout &glyp QVarLengthArray<QFixedPoint> positions; QVarLengthArray<glyph_t> positioned_glyphs; - QTransform matrix; - matrix.translate(x, y - _size); + QTransform matrix = QTransform::fromTranslate(x, y - _size); getGlyphPositions(glyphs, matrix, flags, positioned_glyphs, positions); QSize s(_size - 3, _size - 3); @@ -1186,8 +1193,7 @@ void QFontEngineBox::draw(QPaintEngine *p, qreal x, qreal y, const QTextItemInt QVarLengthArray<QFixedPoint> positions; QVarLengthArray<glyph_t> glyphs; - QTransform matrix; - matrix.translate(x, y - _size); + QTransform matrix = QTransform::fromTranslate(x, y - _size); ti.fontEngine->getGlyphPositions(ti.glyphs, matrix, ti.flags, glyphs, positions); if (glyphs.size() == 0) return; @@ -1646,12 +1652,6 @@ bool QFontEngineMulti::canRender(const QChar *string, int len) return allExist; } -QFontEngine *QFontEngineMulti::engine(int at) const -{ - Q_ASSERT(at < engines.size()); - return engines.at(at); -} - QImage QFontEngineMulti::alphaMapForGlyph(glyph_t) { Q_ASSERT(false); diff --git a/src/gui/text/qfontengine_ft.cpp b/src/gui/text/qfontengine_ft.cpp index ae17a0a..497158f 100644 --- a/src/gui/text/qfontengine_ft.cpp +++ b/src/gui/text/qfontengine_ft.cpp @@ -1,7 +1,6 @@ /**************************************************************************** ** ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** ** This file is part of the QtGui module of the Qt Toolkit. @@ -21,9 +20,10 @@ ** ensure the GNU Lesser General Public License version 2.1 requirements ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. ** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.1, included in the file LGPL_EXCEPTION.txt in this +** package. ** ** If you have questions regarding the use of this file, please contact ** Nokia at qt-info@nokia.com. @@ -54,8 +54,6 @@ #include <private/qpdf_p.h> #include <private/qharfbuzz_p.h> -#include <private/qpdf_p.h> - #include "qfontengine_ft_p.h" #include <ft2build.h> #include FT_FREETYPE_H @@ -193,6 +191,9 @@ HB_Error QFreetypeFace::getPointInOutline(HB_Glyph glyph, int flags, hb_uint32 p /* * One font file can contain more than one font (bold/italic for example) * find the right one and return it. + * + * Returns the freetype face or 0 in case of an empty file or any other problems + * (like not being able to open the file) */ QFreetypeFace *QFreetypeFace::getFace(const QFontEngine::FaceId &face_id) { @@ -204,8 +205,10 @@ QFreetypeFace *QFreetypeFace::getFace(const QFontEngine::FaceId &face_id) FT_Init_FreeType(&freetypeData->library); QFreetypeFace *freetype = freetypeData->faces.value(face_id, 0); - if (!freetype) { - freetype = new QFreetypeFace; + if (freetype) { + freetype->ref.ref(); + } else { + QScopedPointer<QFreetypeFace> newFreetype(new QFreetypeFace); FT_Face face; QFile file(QString::fromUtf8(face_id.filename)); if (face_id.filename.startsWith(":qmemoryfonts/")) { @@ -214,86 +217,90 @@ QFreetypeFace *QFreetypeFace::getFace(const QFontEngine::FaceId &face_id) QByteArray idx = face_id.filename; idx.remove(0, 14); // remove ':qmemoryfonts/' bool ok = false; - freetype->fontData = qt_fontdata_from_index(idx.toInt(&ok)); + newFreetype->fontData = qt_fontdata_from_index(idx.toInt(&ok)); if (!ok) - freetype->fontData = QByteArray(); + newFreetype->fontData = QByteArray(); } else if (!(file.fileEngine()->fileFlags(QAbstractFileEngine::FlagsMask) & QAbstractFileEngine::LocalDiskFlag)) { if (!file.open(QIODevice::ReadOnly)) { - delete freetype; return 0; } - freetype->fontData = file.readAll(); + newFreetype->fontData = file.readAll(); } - if (!freetype->fontData.isEmpty()) { - if (FT_New_Memory_Face(freetypeData->library, (const FT_Byte *)freetype->fontData.constData(), freetype->fontData.size(), face_id.index, &face)) { - delete freetype; + if (!newFreetype->fontData.isEmpty()) { + if (FT_New_Memory_Face(freetypeData->library, (const FT_Byte *)newFreetype->fontData.constData(), newFreetype->fontData.size(), face_id.index, &face)) { return 0; } } else if (FT_New_Face(freetypeData->library, face_id.filename, face_id.index, &face)) { - delete freetype; return 0; } - freetype->face = face; - - freetype->hbFace = qHBNewFace(face, hb_getSFntTable); - freetype->ref = 0; - freetype->xsize = 0; - freetype->ysize = 0; - freetype->matrix.xx = 0x10000; - freetype->matrix.yy = 0x10000; - freetype->matrix.xy = 0; - freetype->matrix.yx = 0; - freetype->unicode_map = 0; - freetype->symbol_map = 0; + newFreetype->face = face; + + newFreetype->hbFace = qHBNewFace(face, hb_getSFntTable); + Q_CHECK_PTR(newFreetype->hbFace); + newFreetype->ref = 1; + newFreetype->xsize = 0; + newFreetype->ysize = 0; + newFreetype->matrix.xx = 0x10000; + newFreetype->matrix.yy = 0x10000; + newFreetype->matrix.xy = 0; + newFreetype->matrix.yx = 0; + newFreetype->unicode_map = 0; + newFreetype->symbol_map = 0; #ifndef QT_NO_FONTCONFIG - freetype->charset = 0; + newFreetype->charset = 0; #endif - memset(freetype->cmapCache, 0, sizeof(freetype->cmapCache)); + memset(newFreetype->cmapCache, 0, sizeof(newFreetype->cmapCache)); - for (int i = 0; i < freetype->face->num_charmaps; ++i) { - FT_CharMap cm = freetype->face->charmaps[i]; + for (int i = 0; i < newFreetype->face->num_charmaps; ++i) { + FT_CharMap cm = newFreetype->face->charmaps[i]; switch(cm->encoding) { case FT_ENCODING_UNICODE: - freetype->unicode_map = cm; + newFreetype->unicode_map = cm; break; case FT_ENCODING_APPLE_ROMAN: case FT_ENCODING_ADOBE_LATIN_1: - if (!freetype->unicode_map || freetype->unicode_map->encoding != FT_ENCODING_UNICODE) - freetype->unicode_map = cm; + if (!newFreetype->unicode_map || newFreetype->unicode_map->encoding != FT_ENCODING_UNICODE) + newFreetype->unicode_map = cm; break; case FT_ENCODING_ADOBE_CUSTOM: case FT_ENCODING_MS_SYMBOL: - if (!freetype->symbol_map) - freetype->symbol_map = cm; + if (!newFreetype->symbol_map) + newFreetype->symbol_map = cm; break; default: break; } } - if (!FT_IS_SCALABLE(freetype->face) && freetype->face->num_fixed_sizes == 1) - FT_Set_Char_Size (face, X_SIZE(freetype->face, 0), Y_SIZE(freetype->face, 0), 0, 0); + if (!FT_IS_SCALABLE(newFreetype->face) && newFreetype->face->num_fixed_sizes == 1) + FT_Set_Char_Size (face, X_SIZE(newFreetype->face, 0), Y_SIZE(newFreetype->face, 0), 0, 0); # if 0 FcChar8 *name; FcPatternGetString(pattern, FC_FAMILY, 0, &name); qDebug("%s: using maps: default: %x unicode: %x, symbol: %x", name, - freetype->face->charmap ? freetype->face->charmap->encoding : 0, - freetype->unicode_map ? freetype->unicode_map->encoding : 0, - freetype->symbol_map ? freetype->symbol_map->encoding : 0); + newFreetype->face->charmap ? newFreetype->face->charmap->encoding : 0, + newFreetype->unicode_map ? newFreetype->unicode_map->encoding : 0, + newFreetype->symbol_map ? newFreetype->symbol_map->encoding : 0); for (int i = 0; i < 256; i += 8) qDebug(" %x: %d %d %d %d %d %d %d %d", i, - FcCharSetHasChar(freetype->charset, i), FcCharSetHasChar(freetype->charset, i), - FcCharSetHasChar(freetype->charset, i), FcCharSetHasChar(freetype->charset, i), - FcCharSetHasChar(freetype->charset, i), FcCharSetHasChar(freetype->charset, i), - FcCharSetHasChar(freetype->charset, i), FcCharSetHasChar(freetype->charset, i)); + FcCharSetHasChar(newFreetype->charset, i), FcCharSetHasChar(newFreetype->charset, i), + FcCharSetHasChar(newFreetype->charset, i), FcCharSetHasChar(newFreetype->charset, i), + FcCharSetHasChar(newFreetype->charset, i), FcCharSetHasChar(newFreetype->charset, i), + FcCharSetHasChar(newFreetype->charset, i), FcCharSetHasChar(newFreetype->charset, i)); #endif - FT_Set_Charmap(freetype->face, freetype->unicode_map); - freetypeData->faces.insert(face_id, freetype); + FT_Set_Charmap(newFreetype->face, newFreetype->unicode_map); + QT_TRY { + freetypeData->faces.insert(face_id, newFreetype.data()); + } QT_CATCH(...) { + newFreetype.take()->release(face_id); + // we could return null in principle instead of throwing + QT_RETHROW; + } + freetype = newFreetype.take(); } - freetype->ref.ref(); return freetype; } @@ -307,7 +314,8 @@ void QFreetypeFace::release(const QFontEngine::FaceId &face_id) if (charset) FcCharSetDestroy(charset); #endif - freetypeData->faces.take(face_id); + if(freetypeData->faces.contains(face_id)) + freetypeData->faces.take(face_id); delete this; } if (freetypeData->faces.isEmpty()) { @@ -608,6 +616,7 @@ QFontEngineFT::QFontEngineFT(const QFontDef &fd) kerning_pairs_loaded = false; transform = false; antialias = true; + freetype = 0; default_load_flags = 0; default_hint_style = HintNone; subpixelType = Subpixel_None; @@ -1380,8 +1389,8 @@ bool QFontEngineFT::loadGlyphs(QGlyphSet *gs, glyph_t *glyphs, int num_glyphs, G FT_Face face = 0; for (int i = 0; i < num_glyphs; ++i) { - if (!gs->glyph_data.contains(glyphs[i]) - || gs->glyph_data.value(glyphs[i])->format != format) { + Glyph *glyph = gs->glyph_data.value(glyphs[i]); + if (glyph == 0 || glyph->format != format) { if (!face) { face = lockFace(); FT_Matrix m = matrix; diff --git a/src/gui/text/qfontengine_ft_p.h b/src/gui/text/qfontengine_ft_p.h index bb4fdeb..4cc5c5e 100644 --- a/src/gui/text/qfontengine_ft_p.h +++ b/src/gui/text/qfontengine_ft_p.h @@ -1,7 +1,6 @@ /**************************************************************************** ** ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** ** This file is part of the QtGui module of the Qt Toolkit. @@ -21,9 +20,10 @@ ** ensure the GNU Lesser General Public License version 2.1 requirements ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. ** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.1, included in the file LGPL_EXCEPTION.txt in this +** package. ** ** If you have questions regarding the use of this file, please contact ** Nokia at qt-info@nokia.com. @@ -119,6 +119,7 @@ struct QFreetypeFace static void addBitmapToPath(FT_GlyphSlot slot, const QFixedPoint &point, QPainterPath *path, bool = false); private: + friend class QScopedPointerDeleter<QFreetypeFace>; QFreetypeFace() : _lock(QMutex::Recursive) {} ~QFreetypeFace() {} QAtomicInt ref; @@ -255,7 +256,7 @@ public: QGlyphSet *loadTransformedGlyphSet(const QTransform &matrix); bool loadGlyphs(QGlyphSet *gs, glyph_t *glyphs, int num_glyphs, GlyphFormat format = Format_Render); -#if defined(Q_WS_QWS) +#if defined(Q_WS_QWS) || defined(Q_OS_SYMBIAN) virtual void draw(QPaintEngine * /*p*/, qreal /*x*/, qreal /*y*/, const QTextItemInt & /*si*/) {} #endif diff --git a/src/gui/text/qfontengine_mac.mm b/src/gui/text/qfontengine_mac.mm index 943e3ab..f32810b 100644 --- a/src/gui/text/qfontengine_mac.mm +++ b/src/gui/text/qfontengine_mac.mm @@ -1,7 +1,6 @@ /**************************************************************************** ** ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** ** This file is part of the QtGui module of the Qt Toolkit. @@ -21,9 +20,10 @@ ** ensure the GNU Lesser General Public License version 2.1 requirements ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. ** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.1, included in the file LGPL_EXCEPTION.txt in this +** package. ** ** If you have questions regarding the use of this file, please contact ** Nokia at qt-info@nokia.com. @@ -135,12 +135,12 @@ QCoreTextFontEngineMulti::QCoreTextFontEngineMulti(const ATSFontFamilyRef &, con symbolicTraits |= kCTFontItalicTrait; break; } - + QCFString name; ATSFontGetName(atsFontRef, kATSOptionFlagsDefault, &name); - QCFType<CTFontDescriptorRef> descriptor = CTFontDescriptorCreateWithNameAndSize(name, fontDef.pixelSize); - QCFType<CTFontRef> baseFont = CTFontCreateWithFontDescriptor(descriptor, fontDef.pixelSize, 0); - ctfont = CTFontCreateCopyWithSymbolicTraits(baseFont, fontDef.pixelSize, 0, symbolicTraits, symbolicTraits); + QCFType<CTFontDescriptorRef> descriptor = CTFontDescriptorCreateWithNameAndSize(name, fontDef.pointSize); + QCFType<CTFontRef> baseFont = CTFontCreateWithFontDescriptor(descriptor, fontDef.pointSize, 0); + ctfont = CTFontCreateCopyWithSymbolicTraits(baseFont, fontDef.pointSize, 0, symbolicTraits, symbolicTraits); // CTFontCreateCopyWithSymbolicTraits returns NULL if we ask for a trait that does // not exist for the given font. (for example italic) @@ -162,7 +162,7 @@ QCoreTextFontEngineMulti::QCoreTextFontEngineMulti(const ATSFontFamilyRef &, con QCoreTextFontEngine *fe = new QCoreTextFontEngine(ctfont, fontDef, this); fe->ref.ref(); engines.append(fe); - + } QCoreTextFontEngineMulti::~QCoreTextFontEngineMulti() @@ -176,7 +176,7 @@ uint QCoreTextFontEngineMulti::fontIndexForFont(CTFontRef id) const if (CFEqual(engineAt(i)->ctfont, id)) return i; } - + QCoreTextFontEngineMulti *that = const_cast<QCoreTextFontEngineMulti *>(this); QCoreTextFontEngine *fe = new QCoreTextFontEngine(id, fontDef, that); fe->ref.ref(); @@ -227,7 +227,7 @@ bool QCoreTextFontEngineMulti::stringToCMap(const QChar *str, int len, QGlyphLay CTFontRef runFont = static_cast<CTFontRef>(CFDictionaryGetValue(runAttribs, NSFontAttributeName)); const uint fontIndex = (fontIndexForFont(runFont) << 24); //NSLog(@"Run Font Name = %@", CTFontCopyFamilyName(runFont)); - QVarLengthArray<CGGlyph, 512> cgglyphs(0); + QVarLengthArray<CGGlyph, 512> cgglyphs(0); const CGGlyph *tmpGlyphs = CTRunGetGlyphsPtr(run); if (!tmpGlyphs) { cgglyphs.resize(glyphCount); @@ -260,7 +260,7 @@ bool QCoreTextFontEngineMulti::stringToCMap(const QChar *str, int len, QGlyphLay CFIndex k = 0; CFIndex i = 0; - for (i = stringRange.location; + for (i = stringRange.location; (i < stringRange.location + stringRange.length) && (k < glyphCount); ++i) { if (tmpIndices[k * rtlSign + rtlOffset] == i || i == stringRange.location) { logClusters[i] = k + firstGlyphIndex; @@ -425,28 +425,28 @@ void QCoreTextFontEngine::draw(CGContextRef ctx, qreal x, qreal y, const QTextIt getGlyphPositions(ti.glyphs, matrix, ti.flags, glyphs, positions); if (glyphs.size() == 0) return; - + CGContextSetFontSize(ctx, fontDef.pixelSize); - + CGAffineTransform oldTextMatrix = CGContextGetTextMatrix(ctx); - + CGAffineTransform cgMatrix = CGAffineTransformMake(1, 0, 0, -1, 0, -paintDeviceHeight); - + CGAffineTransformConcat(cgMatrix, oldTextMatrix); - + if (synthesisFlags & QFontEngine::SynthesizedItalic) cgMatrix = CGAffineTransformConcat(cgMatrix, CGAffineTransformMake(1, 0, -tanf(14 * acosf(0) / 90), 1, 0, 0)); - + // ### cgMatrix = CGAffineTransformConcat(cgMatrix, transform); - + CGContextSetTextMatrix(ctx, cgMatrix); - + CGContextSetTextDrawingMode(ctx, kCGTextFill); - - + + QVarLengthArray<CGSize> advances(glyphs.size()); QVarLengthArray<CGGlyph> cgGlyphs(glyphs.size()); - + for (int i = 0; i < glyphs.size() - 1; ++i) { advances[i].width = (positions[i + 1].x - positions[i].x).toReal(); advances[i].height = (positions[i + 1].y - positions[i].y).toReal(); @@ -455,21 +455,21 @@ void QCoreTextFontEngine::draw(CGContextRef ctx, qreal x, qreal y, const QTextIt advances[glyphs.size() - 1].width = 0; advances[glyphs.size() - 1].height = 0; cgGlyphs[glyphs.size() - 1] = glyphs[glyphs.size() - 1]; - + CGContextSetFont(ctx, cgFont); //NSLog(@"Font inDraw %@ ctfont %@", CGFontCopyFullName(cgFont), CTFontCopyFamilyName(ctfont)); - + CGContextSetTextPosition(ctx, positions[0].x.toReal(), positions[0].y.toReal()); - + CGContextShowGlyphsWithAdvances(ctx, cgGlyphs.data(), advances.data(), glyphs.size()); - + if (synthesisFlags & QFontEngine::SynthesizedBold) { CGContextSetTextPosition(ctx, positions[0].x.toReal() + 0.5 * lineThickness().toReal(), positions[0].y.toReal()); - + CGContextShowGlyphsWithAdvances(ctx, cgGlyphs.data(), advances.data(), glyphs.size()); } - + CGContextSetTextMatrix(ctx, oldTextMatrix); } @@ -540,14 +540,9 @@ QImage QCoreTextFontEngine::alphaMapForGlyph(glyph_t glyph) im.fill(0); CGColorSpaceRef colorspace = QCoreGraphicsPaintEngine::macGenericColorSpace(); -#if (MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_4) uint cgflags = kCGImageAlphaNoneSkipFirst; #ifdef kCGBitmapByteOrder32Host //only needed because CGImage.h added symbols in the minor version - if(QSysInfo::MacintoshVersion >= QSysInfo::MV_10_4) - cgflags |= kCGBitmapByteOrder32Host; -#endif -#else - CGImageAlphaInfo cgflags = kCGImageAlphaNoneSkipFirst; + cgflags |= kCGBitmapByteOrder32Host; #endif CGContextRef ctx = CGBitmapContextCreate(im.bits(), im.width(), im.height(), 8, im.bytesPerLine(), colorspace, @@ -624,7 +619,7 @@ QFontEngine::FaceId QCoreTextFontEngine::faceId() const bool QCoreTextFontEngine::canRender(const QChar *string, int len) { - QCFType<CTFontRef> retFont = CTFontCreateForString(ctfont, + QCFType<CTFontRef> retFont = CTFontCreateForString(ctfont, QCFType<CFStringRef>(CFStringCreateWithCharactersNoCopy(0, reinterpret_cast<const UniChar *>(string), len, kCFAllocatorNull)), @@ -674,7 +669,7 @@ QFontEngineMacMulti::QFontEngineMacMulti(const ATSFontFamilyRef &atsFamily, cons } else { if (fontDef.weight >= QFont::Bold) fntStyle |= ::bold; - if (fontDef.style != QFont::StyleNormal) + if (fontDef.style != QFont::StyleNormal) fntStyle |= ::italic; FMFontStyle intrinsicStyle; @@ -957,7 +952,7 @@ bool QFontEngineMacMulti::stringToCMap(const QChar *str, int len, QGlyphLayout * tmpItem.length = charCount; tmpItem.glyphs = shaperItem.glyphs.mid(glyphIdx, glyphCount); tmpItem.log_clusters = shaperItem.log_clusters + charIdx; - if (!stringToCMapInternal(tmpItem.string + tmpItem.from, tmpItem.length, + if (!stringToCMapInternal(tmpItem.string + tmpItem.from, tmpItem.length, &tmpItem.glyphs, &glyphCount, flags, &tmpItem)) { *nglyphs = glyphIdx + glyphCount; @@ -1218,12 +1213,12 @@ QFontEngineMac::QFontEngineMac(ATSUStyle baseStyle, ATSUFontID fontID, const QFo transform = multiEngine->transform; else transform = CGAffineTransformIdentity; - + ATSUTextMeasurement metric; ATSUGetAttribute(style, kATSUAscentTag, sizeof(metric), &metric, 0); m_ascent = FixRound(metric); - + ATSUGetAttribute(style, kATSUDescentTag, sizeof(metric), &metric, 0); m_descent = FixRound(metric); @@ -1419,21 +1414,21 @@ void QFontEngineMac::addGlyphsToPath(glyph_t *glyphs, QFixedPoint *positions, in addGlyphsToPathHelper(style, glyphs, positions, numGlyphs, path); } -QImage QFontEngineMac::alphaMapForGlyph(glyph_t glyph) + +/*! + Helper function for alphaMapForGlyph and alphaRGBMapForGlyph. The two are identical, except for + the subpixel antialiasing... +*/ +QImage QFontEngineMac::imageForGlyph(glyph_t glyph, int margin, bool colorful) { const glyph_metrics_t br = boundingBox(glyph); QImage im(qRound(br.width)+2, qRound(br.height)+4, QImage::Format_RGB32); - im.fill(0); + im.fill(0xff000000); CGColorSpaceRef colorspace = QCoreGraphicsPaintEngine::macGenericColorSpace(); -#if (MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_4) uint cgflags = kCGImageAlphaNoneSkipFirst; #ifdef kCGBitmapByteOrder32Host //only needed because CGImage.h added symbols in the minor version - if(QSysInfo::MacintoshVersion >= QSysInfo::MV_10_4) - cgflags |= kCGBitmapByteOrder32Host; -#endif -#else - CGImageAlphaInfo cgflags = kCGImageAlphaNoneSkipFirst; + cgflags |= kCGBitmapByteOrder32Host; #endif CGContextRef ctx = CGBitmapContextCreate(im.bits(), im.width(), im.height(), 8, im.bytesPerLine(), colorspace, @@ -1441,7 +1436,7 @@ QImage QFontEngineMac::alphaMapForGlyph(glyph_t glyph) CGContextSetFontSize(ctx, fontDef.pixelSize); CGContextSetShouldAntialias(ctx, fontDef.pointSize > qt_antialiasing_threshold && !(fontDef.styleStrategy & QFont::NoAntialias)); // turn off sub-pixel hinting - no support for that in OpenGL - CGContextSetShouldSmoothFonts(ctx, false); + CGContextSetShouldSmoothFonts(ctx, colorful); CGAffineTransform oldTextMatrix = CGContextGetTextMatrix(ctx); CGAffineTransform cgMatrix = CGAffineTransformMake(1, 0, 0, 1, 0, 0); CGAffineTransformConcat(cgMatrix, oldTextMatrix); @@ -1473,6 +1468,13 @@ QImage QFontEngineMac::alphaMapForGlyph(glyph_t glyph) CGContextRelease(ctx); + return im; +} + +QImage QFontEngineMac::alphaMapForGlyph(glyph_t glyph) +{ + QImage im = imageForGlyph(glyph, 2, false); + QImage indexed(im.width(), im.height(), QImage::Format_Indexed8); QVector<QRgb> colors(256); for (int i=0; i<256; ++i) @@ -1492,6 +1494,32 @@ QImage QFontEngineMac::alphaMapForGlyph(glyph_t glyph) return indexed; } +QImage QFontEngineMac::alphaRGBMapForGlyph(glyph_t glyph, int margin, const QTransform &t) +{ + QImage im = imageForGlyph(glyph, margin, true); + + if (t.type() >= QTransform::TxScale) { + im = im.transformed(t); + } + + extern uchar qt_pow_rgb_gamma[256]; + + // gamma correct the pixels back to linear color space... + for (int y=0; y<im.height(); ++y) { + uint *pixels = (uint *) im.scanLine(y); + for (int x=0; x<im.width(); ++x) { + uint p = pixels[x]; + uint r = qt_pow_rgb_gamma[qRed(p)]; + uint g = qt_pow_rgb_gamma[qGreen(p)]; + uint b = qt_pow_rgb_gamma[qBlue(p)]; + pixels[x] = (r << 16) | (g << 8) | b | 0xff000000; + } + } + + return im; +} + + bool QFontEngineMac::canRender(const QChar *string, int len) { Q_ASSERT(false); @@ -1648,7 +1676,7 @@ QFontEngine::Properties QFontEngineMac::properties() const if (ATSFontGetTable(atsFont, MAKE_TAG('p', 'o', 's', 't'), 10, 2, &lw, 0) == noErr) lw = qFromBigEndian<quint16>(lw); props.lineWidth = lw; - + // CTFontCopyPostScriptName QCFString psName; if (ATSFontGetPostScriptName(FMGetATSFontRefFromFont(fontID), kATSOptionFlagsDefault, &psName) == noErr) @@ -1663,7 +1691,7 @@ void QFontEngineMac::getUnscaledGlyph(glyph_t glyph, QPainterPath *path, glyph_m ATSUCreateAndCopyStyle(style, &unscaledStyle); int emSquare = properties().emSquare.toInt(); - + const int maxAttributeCount = 4; ATSUAttributeTag tags[maxAttributeCount + 1]; ByteCount sizes[maxAttributeCount + 1]; @@ -1675,7 +1703,7 @@ void QFontEngineMac::getUnscaledGlyph(glyph_t glyph, QPainterPath *path, glyph_m sizes[attributeCount] = sizeof(size); values[attributeCount] = &size; ++attributeCount; - + Q_ASSERT(attributeCount < maxAttributeCount + 1); OSStatus err = ATSUSetAttributes(unscaledStyle, attributeCount, tags, sizes, values); Q_ASSERT(err == noErr); diff --git a/src/gui/text/qfontengine_p.h b/src/gui/text/qfontengine_p.h index 584302e..d654215 100644 --- a/src/gui/text/qfontengine_p.h +++ b/src/gui/text/qfontengine_p.h @@ -1,7 +1,6 @@ /**************************************************************************** ** ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** ** This file is part of the QtGui module of the Qt Toolkit. @@ -21,9 +20,10 @@ ** ensure the GNU Lesser General Public License version 2.1 requirements ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. ** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.1, included in the file LGPL_EXCEPTION.txt in this +** package. ** ** If you have questions regarding the use of this file, please contact ** Nokia at qt-info@nokia.com. @@ -70,7 +70,7 @@ # include "private/qcore_mac_p.h" #endif -#include "qfontengineglyphcache_p.h" +#include <private/qfontengineglyphcache_p.h> struct glyph_metrics_t; typedef unsigned int glyph_t; @@ -93,7 +93,6 @@ struct QGlyphLayout; class Q_GUI_EXPORT QFontEngine : public QObject { - Q_OBJECT public: enum Type { Box, @@ -108,11 +107,15 @@ public: // Apple Mac OS types Mac, - // Trolltech QWS types + // QWS types Freetype, QPF1, QPF2, Proxy, + + // S60 types + S60FontEngine, // Cannot be simply called "S60". Reason is qt_s60Data.h + TestFontEngine = 0x1000 }; @@ -164,7 +167,7 @@ public: virtual void recalcAdvances(QGlyphLayout *, QTextEngine::ShaperFlags) const {} virtual void doKerning(QGlyphLayout *, QTextEngine::ShaperFlags) const; -#if !defined(Q_WS_X11) && !defined(Q_WS_WIN) && !defined(Q_WS_MAC) +#if !defined(Q_WS_X11) && !defined(Q_WS_WIN) && !defined(Q_WS_MAC) && !defined(Q_OS_SYMBIAN) virtual void draw(QPaintEngine *p, qreal x, qreal y, const QTextItemInt &si) = 0; #endif virtual void addGlyphsToPath(glyph_t *glyphs, QFixedPoint *positions, int nglyphs, @@ -231,7 +234,7 @@ public: bool symbol; mutable HB_FontRec hbFont; mutable HB_Face hbFace; -#if defined(Q_WS_WIN) || defined(Q_WS_X11) || defined(Q_WS_QWS) +#if defined(Q_WS_WIN) || defined(Q_WS_X11) || defined(Q_WS_QWS) || defined(Q_OS_SYMBIAN) struct KernPair { uint left_right; QFixed adjust; @@ -247,6 +250,9 @@ public: int glyphFormat; +protected: + static const QVector<QRgb> &grayPalette(); + private: /// remove old entries from the glyph cache. Helper method for the setGlyphCache ones. void expireGlyphCache(); @@ -322,7 +328,7 @@ public: virtual bool stringToCMap(const QChar *str, int len, QGlyphLayout *glyphs, int *nglyphs, QTextEngine::ShaperFlags flags) const; virtual void recalcAdvances(QGlyphLayout *, QTextEngine::ShaperFlags) const; -#if !defined(Q_WS_X11) && !defined(Q_WS_WIN) && !defined(Q_WS_MAC) +#if !defined(Q_WS_X11) && !defined(Q_WS_WIN) && !defined(Q_WS_MAC) && !defined(Q_OS_SYMBIAN) void draw(QPaintEngine *p, qreal x, qreal y, const QTextItemInt &si); #endif virtual void addOutlineToPath(qreal x, qreal y, const QGlyphLayout &glyphs, QPainterPath *path, QTextItem::RenderFlags flags); @@ -353,7 +359,7 @@ private: int _size; }; -class Q_GUI_EXPORT QFontEngineMulti : public QFontEngine +class QFontEngineMulti : public QFontEngine { public: explicit QFontEngineMulti(int engineCount); @@ -389,7 +395,9 @@ public: inline virtual const char *name() const { return "Multi"; } - QFontEngine *engine(int at) const; + QFontEngine *engine(int at) const + {Q_ASSERT(at < engines.size()); return engines.at(at); } + protected: friend class QPSPrintEnginePrivate; @@ -525,8 +533,11 @@ public: virtual Properties properties() const; virtual void getUnscaledGlyph(glyph_t glyph, QPainterPath *path, glyph_metrics_t *metrics); virtual QImage alphaMapForGlyph(glyph_t); + virtual QImage alphaRGBMapForGlyph(glyph_t, int margin, const QTransform &t); private: + QImage imageForGlyph(glyph_t glyph, int margin, bool colorful); + ATSUFontID fontID; QCFType<CGFontRef> cgFont; ATSUStyle style; @@ -614,4 +625,8 @@ QT_END_NAMESPACE # include "private/qfontengine_win_p.h" #endif +#if defined(Q_OS_SYMBIAN) && !defined(QT_NO_FREETYPE) +# include "private/qfontengine_ft_p.h" +#endif + #endif // QFONTENGINE_P_H diff --git a/src/gui/text/qfontengine_qpf.cpp b/src/gui/text/qfontengine_qpf.cpp index b940af5..7c8be82 100644 --- a/src/gui/text/qfontengine_qpf.cpp +++ b/src/gui/text/qfontengine_qpf.cpp @@ -1,7 +1,6 @@ /**************************************************************************** ** ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** ** This file is part of the QtGui module of the Qt Toolkit. @@ -21,9 +20,10 @@ ** ensure the GNU Lesser General Public License version 2.1 requirements ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. ** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.1, included in the file LGPL_EXCEPTION.txt in this +** package. ** ** If you have questions regarding the use of this file, please contact ** Nokia at qt-info@nokia.com. @@ -51,6 +51,7 @@ #if !defined(QT_NO_FREETYPE) #include "private/qfontengine_ft_p.h" #endif +#include "private/qcore_unix_p.h" // overrides QT_OPEN // for mmap #include <stdlib.h> @@ -65,9 +66,10 @@ QT_BEGIN_NAMESPACE #ifndef QT_NO_QWS_QPF2 -QT_BEGIN_INCLUDE_NAMESPACE #include "qpfutil.cpp" +QT_BEGIN_INCLUDE_NAMESPACE + #if defined(Q_WS_QWS) # include "private/qwscommand_qws_p.h" # include "qwsdisplay_qws.h" @@ -252,7 +254,7 @@ QList<QByteArray> QFontEngineQPF::cleanUpAfterClientCrash(const QList<int> &cras for (int i = 0; i < int(dir.count()); ++i) { const QByteArray fileName = QFile::encodeName(dir.absoluteFilePath(dir[i])); - int fd = ::open(fileName.constData(), O_RDONLY); + int fd = QT_OPEN(fileName.constData(), O_RDONLY, 0); if (fd >= 0) { void *header = ::mmap(0, sizeof(QFontEngineQPF::Header), PROT_READ, MAP_SHARED, fd, 0); if (header && header != MAP_FAILED) { @@ -265,7 +267,7 @@ QList<QByteArray> QFontEngineQPF::cleanUpAfterClientCrash(const QList<int> &cras ::munmap(header, sizeof(QFontEngineQPF::Header)); } - ::close(fd); + QT_CLOSE(fd); } } if (!removedFonts.isEmpty()) @@ -308,7 +310,7 @@ QFontEngineQPF::QFontEngineQPF(const QFontDef &def, int fileDescriptor, QFontEng readOnly = true; #if defined(DEBUG_FONTENGINE) - qDebug() << "QFontEngineQPF::QFontEngineQPF( fd =" << fd << ", renderingFontEngine =" << renderingFontEngine << ")"; + qDebug() << "QFontEngineQPF::QFontEngineQPF( fd =" << fd << ", renderingFontEngine =" << renderingFontEngine << ')'; #endif #ifndef QT_FONTS_ARE_RESOURCES @@ -316,30 +318,51 @@ QFontEngineQPF::QFontEngineQPF(const QFontDef &def, int fileDescriptor, QFontEng if (!renderingFontEngine) return; - fileName = fontDef.family.toLower() + QLatin1String("_") + fileName = fontDef.family.toLower() + QLatin1Char('_') + QString::number(fontDef.pixelSize) - + QLatin1String("_") + QString::number(fontDef.weight) + + QLatin1Char('_') + QString::number(fontDef.weight) + (fontDef.style != QFont::StyleNormal ? QLatin1String("_italic") : QLatin1String("")) + QLatin1String(".qsf"); fileName.replace(QLatin1Char(' '), QLatin1Char('_')); fileName.prepend(qws_fontCacheDir()); - const QByteArray encodedName = QFile::encodeName(fileName); - if (::access(encodedName, F_OK) == 0) { + encodedFileName = QFile::encodeName(fileName); + if (::access(encodedFileName, F_OK) == 0) { #if defined(DEBUG_FONTENGINE) qDebug() << "found existing qpf:" << fileName; #endif - if (::access(encodedName, W_OK | R_OK) == 0) - fd = ::open(encodedName, O_RDWR); - else if (::access(encodedName, R_OK) == 0) - fd = ::open(encodedName, O_RDONLY); + if (::access(encodedFileName, W_OK | R_OK) == 0) { + fd = QT_OPEN(encodedFileName, O_RDWR); + } + // read-write access failed - try read-only access + if (fd == -1 && ::access(encodedFileName, R_OK) == 0) { + fd = QT_OPEN(encodedFileName, O_RDONLY); + if (fd == -1) { +#if defined(DEBUG_FONTENGINE) + qErrnoWarning("QFontEngineQPF: unable to open %s", encodedName.constData()); +#endif + return; + } + } + if (fd == -1) { +#if defined(DEBUG_FONTENGINE) + qWarning("QFontEngineQPF: insufficient access rights to %s", encodedName.constData()); +#endif + return; + } } else { #if defined(DEBUG_FONTENGINE) qDebug() << "creating qpf on the fly:" << fileName; #endif if (::access(QFile::encodeName(qws_fontCacheDir()), W_OK) == 0) { - fd = ::open(encodedName, O_RDWR | O_EXCL | O_CREAT, 0644); + fd = QT_OPEN(encodedFileName, O_RDWR | O_EXCL | O_CREAT, 0644); + if (fd == -1) { +#if defined(DEBUG_FONTENGINE) + qErrnoWarning(errno, "QFontEngineQPF: open() failed for %s", encodedName.constData()); +#endif + return; + } QBuffer buffer; buffer.open(QIODevice::ReadWrite); @@ -347,7 +370,17 @@ QFontEngineQPF::QFontEngineQPF(const QFontDef &def, int fileDescriptor, QFontEng generator.generate(); buffer.close(); const QByteArray &data = buffer.data(); - ::write(fd, data.constData(), data.size()); + if (QT_WRITE(fd, data.constData(), data.size()) == -1) { +#if defined(DEBUG_FONTENGINE) + qErrnoWarning(errno, "QFontEngineQPF: write() failed for %s", encodedName.constData()); +#endif + return; + } + } else { +#if defined(DEBUG_FONTENGINE) + qErrnoWarning(errno, "QFontEngineQPF: access() failed for %s", qPrintable(qws_fontCacheDir())); +#endif + return; } } } @@ -355,7 +388,7 @@ QFontEngineQPF::QFontEngineQPF(const QFontDef &def, int fileDescriptor, QFontEng QT_STATBUF st; if (QT_FSTAT(fd, &st)) { #if defined(DEBUG_FONTENGINE) - qDebug() << "stat failed!"; + qErrnoWarning(errno, "QFontEngineQPF: fstat failed!"); #endif return; } @@ -474,19 +507,30 @@ QFontEngineQPF::QFontEngineQPF(const QFontDef &def, int fileDescriptor, QFontEng #endif #if defined(Q_WS_QWS) if (isValid() && renderingFontEngine) - qt_fbdpy->sendFontCommand(QWSFontCommand::StartedUsingFont, QFile::encodeName(fileName)); + qt_fbdpy->sendFontCommand(QWSFontCommand::StartedUsingFont, encodedFileName); #endif } QFontEngineQPF::~QFontEngineQPF() { #if defined(Q_WS_QWS) - if (isValid() && renderingFontEngine) - qt_fbdpy->sendFontCommand(QWSFontCommand::StoppedUsingFont, QFile::encodeName(fileName)); + if (isValid() && renderingFontEngine) { + QT_TRY { + qt_fbdpy->sendFontCommand(QWSFontCommand::StoppedUsingFont, encodedFileName); + } QT_CATCH(...) { + qDebug("QFontEngineQPF::~QFontEngineQPF: Out of memory"); + // ignore. + } + } #endif delete renderingFontEngine; - if (fontData) - munmap((void *)fontData, dataSize); + if (fontData) { + if (munmap((void *)fontData, dataSize) == -1) { +#if defined(DEBUG_FONTENGINE) + qErrnoWarning(errno, "~QFontEngineQPF: Unable to munmap"); +#endif + } + } if (fd != -1) ::close(fd); #if !defined(QT_NO_FREETYPE) @@ -550,7 +594,7 @@ bool QFontEngineQPF::stringToCMap(const QChar *str, int len, QGlyphLayout *glyph #if 0 && defined(DEBUG_FONTENGINE) QChar c(uc); if (!findGlyph(glyphs[glyph_pos].glyph) && !seenGlyphs.contains(c)) - qDebug() << "glyph for character" << c << "/" << hex << uc << "is" << dec << glyphs[glyph_pos].glyph; + qDebug() << "glyph for character" << c << '/' << hex << uc << "is" << dec << glyphs[glyph_pos].glyph; seenGlyphs.insert(c); #endif @@ -893,8 +937,8 @@ void QFontEngineQPF::loadGlyph(glyph_t glyph) g.y = qRound(metrics.y); g.advance = qRound(metrics.xoff); - ::write(fd, &g, sizeof(g)); - ::write(fd, img.bits(), img.numBytes()); + QT_WRITE(fd, &g, sizeof(g)); + QT_WRITE(fd, img.bits(), img.numBytes()); glyphPos = oldSize - glyphDataOffset; #if 0 && defined(DEBUG_FONTENGINE) @@ -1128,6 +1172,11 @@ void QPFGenerator::writeTaggedQFixed(QFontEngineQPF::HeaderTag tag, QFixed value #endif // QT_NO_QWS_QPF2 +/* + Creates a new multi qws engine. + + This function takes ownership of the QFontEngine, increasing it's refcount. +*/ QFontEngineMultiQWS::QFontEngineMultiQWS(QFontEngine *fe, int _script, const QStringList &fallbacks) : QFontEngineMulti(fallbacks.size() + 1), fallbackFamilies(fallbacks), script(_script) diff --git a/src/gui/text/qfontengine_qpf_p.h b/src/gui/text/qfontengine_qpf_p.h index d7ddab7..6fa0ef7 100644 --- a/src/gui/text/qfontengine_qpf_p.h +++ b/src/gui/text/qfontengine_qpf_p.h @@ -1,7 +1,6 @@ /**************************************************************************** ** ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** ** This file is part of the QtGui module of the Qt Toolkit. @@ -21,9 +20,10 @@ ** ensure the GNU Lesser General Public License version 2.1 requirements ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. ** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.1, included in the file LGPL_EXCEPTION.txt in this +** package. ** ** If you have questions regarding the use of this file, please contact ** Nokia at qt-info@nokia.com. @@ -243,6 +243,7 @@ private: quint32 glyphDataOffset; quint32 glyphDataSize; QString fileName; + QByteArray encodedFileName; bool readOnly; QFreetypeFace *freetype; diff --git a/src/gui/text/qfontengine_qws.cpp b/src/gui/text/qfontengine_qws.cpp index 0c988e0..ce84676 100644 --- a/src/gui/text/qfontengine_qws.cpp +++ b/src/gui/text/qfontengine_qws.cpp @@ -1,7 +1,6 @@ /**************************************************************************** ** ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** ** This file is part of the QtGui module of the Qt Toolkit. @@ -21,9 +20,10 @@ ** ensure the GNU Lesser General Public License version 2.1 requirements ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. ** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.1, included in the file LGPL_EXCEPTION.txt in this +** package. ** ** If you have questions regarding the use of this file, please contact ** Nokia at qt-info@nokia.com. @@ -47,6 +47,7 @@ #include <private/qpaintengine_raster_p.h> #include <private/qpdf_p.h> #include "qtextengine_p.h" +#include "private/qcore_unix_p.h" // overrides QT_OPEN #include <qdebug.h> @@ -387,7 +388,7 @@ QFontEngineQPF1::QFontEngineQPF1(const QFontDef&, const QString &fn) { cache_cost = 1; - int f = ::open( QFile::encodeName(fn), O_RDONLY ); + int f = QT_OPEN( QFile::encodeName(fn), O_RDONLY, 0); Q_ASSERT(f>=0); QT_STATBUF st; if ( QT_FSTAT( f, &st ) ) @@ -395,7 +396,7 @@ QFontEngineQPF1::QFontEngineQPF1(const QFontDef&, const QString &fn) uchar* data = (uchar*)mmap( 0, // any address st.st_size, // whole file PROT_READ, // read-only memory -#if !defined(Q_OS_SOLARIS) && !defined(Q_OS_QNX4) && !defined(Q_OS_INTEGRITY) +#if !defined(Q_OS_SOLARIS) && !defined(Q_OS_QNX4) && !defined(Q_OS_INTEGRITY) && !defined(Q_OS_VXWORKS) MAP_FILE | MAP_PRIVATE, // swap-backed map from file #else MAP_PRIVATE, @@ -406,7 +407,7 @@ QFontEngineQPF1::QFontEngineQPF1(const QFontDef&, const QString &fn) #endif if ( !data || data == (uchar*)MAP_FAILED ) qFatal("Failed to mmap %s",QFile::encodeName(fn).data()); - ::close(f); + QT_CLOSE(f); d = new QFontEngineQPF1Data; memcpy(reinterpret_cast<char*>(&d->fm),data,sizeof(d->fm)); diff --git a/src/gui/text/qfontengine_s60.cpp b/src/gui/text/qfontengine_s60.cpp new file mode 100644 index 0000000..6d636ac --- /dev/null +++ b/src/gui/text/qfontengine_s60.cpp @@ -0,0 +1,331 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtGui of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.1, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qfontengine_s60_p.h" +#include "qtextengine_p.h" +#include "qglobal.h" +#include <private/qapplication_p.h> +#include <private/qwindowsurface_s60_p.h> +#include "qimage.h" +#include "qt_s60_p.h" + +#include <e32base.h> +#include <e32std.h> +#include <EIKENV.H> +#include <GDI.H> + +QT_BEGIN_NAMESPACE + +QFontEngineS60Extensions::QFontEngineS60Extensions(CFont* fontOwner, COpenFont *font) + : m_font(font) + , m_cmap(0) + , m_symbolCMap(false) + , m_fontOwner(fontOwner) +{ + TAny *shapingExtension = NULL; + m_font->ExtendedInterface(KUidOpenFontShapingExtension, shapingExtension); + m_shapingExtension = static_cast<MOpenFontShapingExtension*>(shapingExtension); + TAny *trueTypeExtension = NULL; + m_font->ExtendedInterface(KUidOpenFontTrueTypeExtension, trueTypeExtension); + m_trueTypeExtension = static_cast<MOpenFontTrueTypeExtension*>(trueTypeExtension); + Q_ASSERT(m_shapingExtension && m_trueTypeExtension); +} + +QByteArray QFontEngineS60Extensions::getSfntTable(uint tag) const +{ + Q_ASSERT(m_trueTypeExtension->HasTrueTypeTable(tag)); + TInt error = KErrNone; + TInt tableByteLength = 0; + TAny *table = m_trueTypeExtension->GetTrueTypeTable(error, tag, &tableByteLength); + QByteArray result(static_cast<const char*>(table), tableByteLength); + m_trueTypeExtension->ReleaseTrueTypeTable(table); + return result; +} + +const unsigned char *QFontEngineS60Extensions::cmap() const +{ + if (!m_cmap) { + m_cmapTable = getSfntTable(MAKE_TAG('c', 'm', 'a', 'p')); + int size = 0; + m_cmap = QFontEngineS60::getCMap(reinterpret_cast<const uchar *>(m_cmapTable.constData()), m_cmapTable.size(), &m_symbolCMap, &size); + } + return m_cmap; +} + +QPainterPath QFontEngineS60Extensions::glyphOutline(glyph_t glyph) const +{ + QPainterPath result; + QPolygonF polygon; + TInt glyphIndex = glyph; + TInt pointNumber = 0; + TInt x, y; + while (m_shapingExtension->GlyphPointInFontUnits(glyphIndex, pointNumber++, x, y)) { + const QPointF point(qreal(x) / 0xffff, qreal(y) / 0xffff); + if (polygon.contains(point)) { + result.addPolygon(polygon); + result.closeSubpath(); + polygon.clear(); + } else { + polygon.append(point); + } + } + return result; +} + +CFont *QFontEngineS60Extensions::fontOwner() const +{ + return m_fontOwner; +} + + +// duplicated from qfontengine_xyz.cpp +static inline unsigned int getChar(const QChar *str, int &i, const int len) +{ + unsigned int uc = str[i].unicode(); + if (uc >= 0xd800 && uc < 0xdc00 && i < len-1) { + uint low = str[i+1].unicode(); + if (low >= 0xdc00 && low < 0xe000) { + uc = (uc - 0xd800)*0x400 + (low - 0xdc00) + 0x10000; + ++i; + } + } + return uc; +} + +QFontEngineS60::QFontEngineS60(const QFontDef &request, const QFontEngineS60Extensions *extensions) + : m_extensions(extensions) +{ + QFontEngine::fontDef = request; + m_fontSizeInPixels = (request.pixelSize >= 0)? + request.pixelSize:pointsToPixels(request.pointSize); + QS60WindowSurface::unlockBitmapHeap(); + m_textRenderBitmap = q_check_ptr(new CFbsBitmap()); // CBase derived object needs check on new + const TSize bitmapSize(1, 1); // It is just a dummy bitmap that I need to keep the font alive (or maybe not) + qt_symbian_throwIfError(m_textRenderBitmap->Create(bitmapSize, EGray256)); + QT_TRAP_THROWING(m_textRenderBitmapDevice = CFbsBitmapDevice::NewL(m_textRenderBitmap)); + qt_symbian_throwIfError(m_textRenderBitmapDevice->CreateContext(m_textRenderBitmapGc)); + cache_cost = sizeof(QFontEngineS60) + bitmapSize.iHeight * bitmapSize.iWidth * 4; + + TFontSpec fontSpec(qt_QString2TPtrC(request.family), m_fontSizeInPixels); + fontSpec.iFontStyle.SetBitmapType(EAntiAliasedGlyphBitmap); + fontSpec.iFontStyle.SetPosture(request.style == QFont::StyleNormal?EPostureUpright:EPostureItalic); + fontSpec.iFontStyle.SetStrokeWeight(request.weight > QFont::Normal?EStrokeWeightBold:EStrokeWeightNormal); + const TInt errorCode = m_textRenderBitmapDevice->GetNearestFontInPixels(m_font, fontSpec); + Q_ASSERT(errorCode == 0); + m_textRenderBitmapGc->UseFont(m_font); + QS60WindowSurface::lockBitmapHeap(); +} + +QFontEngineS60::~QFontEngineS60() +{ + QS60WindowSurface::unlockBitmapHeap(); + m_textRenderBitmapGc->DiscardFont(); + delete m_textRenderBitmapGc; + m_textRenderBitmapGc = NULL; + m_textRenderBitmapDevice->ReleaseFont(m_font); + delete m_textRenderBitmapDevice; + m_textRenderBitmapDevice = NULL; + delete m_textRenderBitmap; + m_textRenderBitmap = NULL; + QS60WindowSurface::lockBitmapHeap(); +} + +bool QFontEngineS60::stringToCMap(const QChar *characters, int len, QGlyphLayout *glyphs, int *nglyphs, QTextEngine::ShaperFlags flags) const +{ + if (*nglyphs < len) { + *nglyphs = len; + return false; + } + + HB_Glyph *g = glyphs->glyphs; + const unsigned char* cmap = m_extensions->cmap(); + for (int i = 0; i < len; ++i) { + const unsigned int uc = getChar(characters, i, len); + *g++ = QFontEngine::getTrueTypeGlyphIndex(cmap, uc); + } + + glyphs->numGlyphs = g - glyphs->glyphs; + *nglyphs = glyphs->numGlyphs; + + if (flags & QTextEngine::GlyphIndicesOnly) + return true; + + recalcAdvances(glyphs, flags); + return true; +} + +void QFontEngineS60::recalcAdvances(QGlyphLayout *glyphs, QTextEngine::ShaperFlags flags) const +{ + Q_UNUSED(flags); + for (int i = 0; i < glyphs->numGlyphs; i++) { + const glyph_metrics_t bbox = boundingBox_const(glyphs->glyphs[i]); + glyphs->advances_x[i] = glyphs->offsets[i].x = bbox.xoff; + glyphs->advances_y[i] = glyphs->offsets[i].y = bbox.yoff; + } +} + +QImage QFontEngineS60::alphaMapForGlyph(glyph_t glyph) +{ + TOpenFontCharMetrics metrics; + const TUint8 *glyphBitmapBytes; + TSize glyphBitmapSize; + getCharacterData(glyph, metrics, glyphBitmapBytes, glyphBitmapSize); + QImage result(glyphBitmapBytes, glyphBitmapSize.iWidth, glyphBitmapSize.iHeight, glyphBitmapSize.iWidth, QImage::Format_Indexed8); + result.setColorTable(grayPalette()); + + // The above setColorTable() call detached the image data anyway, so why not shape tha data a bit, while we can. + // CFont::GetCharacterData() returns 8-bit data that obviously was 4-bit data before, and converted to 8-bit incorrectly. + // The data values are 0x00, 0x10 ... 0xe0, 0xf0. So, a real opaque 0xff is never reached, which we get punished + // for every time we want to blit this glyph in the raster paint engine. + // "Fix" is to convert all 0xf0 to 0xff. Is fine, quality wise, and I assume faster than correcting all values. + // Blitting is however, evidentially faster now. + const int bpl = result.bytesPerLine(); + for (int row = 0; row < result.height(); ++row) { + uchar *scanLine = result.scanLine(row); + for (int column = 0; column < bpl; ++column) { + if (*scanLine == 0xf0) + *scanLine = 0xff; + scanLine++; + } + } + + return result; +} + +glyph_metrics_t QFontEngineS60::boundingBox(const QGlyphLayout &glyphs) +{ + if (glyphs.numGlyphs == 0) + return glyph_metrics_t(); + + QFixed w = 0; + for (int i = 0; i < glyphs.numGlyphs; ++i) + w += glyphs.effectiveAdvance(i); + + return glyph_metrics_t(0, -ascent(), w, ascent()+descent()+1, w, 0); +} + +glyph_metrics_t QFontEngineS60::boundingBox_const(glyph_t glyph) const +{ + TOpenFontCharMetrics metrics; + const TUint8 *glyphBitmapBytes; + TSize glyphBitmapSize; + getCharacterData(glyph, metrics, glyphBitmapBytes, glyphBitmapSize); + TRect glyphBounds; + metrics.GetHorizBounds(glyphBounds); + const glyph_metrics_t result( + glyphBounds.iTl.iX, + glyphBounds.iTl.iY, + glyphBounds.Width(), + glyphBounds.Height(), + metrics.HorizAdvance(), + 0 + ); + return result; +} + +glyph_metrics_t QFontEngineS60::boundingBox(glyph_t glyph) +{ + return boundingBox_const(glyph); +} + +QFixed QFontEngineS60::ascent() const +{ + return m_font->FontMaxAscent(); +} + +QFixed QFontEngineS60::descent() const +{ + return m_font->FontMaxDescent(); +} + +QFixed QFontEngineS60::leading() const +{ + return 0; +} + +qreal QFontEngineS60::maxCharWidth() const +{ + return m_font->MaxCharWidthInPixels(); +} + +const char *QFontEngineS60::name() const +{ + return "QFontEngineS60"; +} + +bool QFontEngineS60::canRender(const QChar *string, int len) +{ + const unsigned char *cmap = m_extensions->cmap(); + for (int i = 0; i < len; ++i) { + const unsigned int uc = getChar(string, i, len); + if (QFontEngine::getTrueTypeGlyphIndex(cmap, uc) == 0) + return false; + } + return true; +} + +QByteArray QFontEngineS60::getSfntTable(uint tag) const +{ + return m_extensions->getSfntTable(tag); +} + +QFontEngine::Type QFontEngineS60::type() const +{ + return QFontEngine::S60FontEngine; +} + +void QFontEngineS60::getCharacterData(glyph_t glyph, TOpenFontCharMetrics& metrics, const TUint8*& bitmap, TSize& bitmapSize) const +{ + // Setting the most significant bit tells GetCharacterData + // that 'code' is a Glyph ID, rather than a UTF-16 value + const TUint specialCode = (TUint)glyph | 0x80000000; + + const CFont::TCharacterDataAvailability availability = + m_font->GetCharacterData(specialCode, metrics, bitmap, bitmapSize); + const glyph_t fallbackGlyph = '?'; + if (availability != CFont::EAllCharacterData) { + const CFont::TCharacterDataAvailability fallbackAvailability = + m_font->GetCharacterData(fallbackGlyph, metrics, bitmap, bitmapSize); + Q_ASSERT(fallbackAvailability == CFont::EAllCharacterData); + } +} + +QT_END_NAMESPACE diff --git a/src/gui/text/qfontengine_s60_p.h b/src/gui/text/qfontengine_s60_p.h new file mode 100644 index 0000000..eb3a744 --- /dev/null +++ b/src/gui/text/qfontengine_s60_p.h @@ -0,0 +1,148 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtGui of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.1, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QFONTENGINE_S60_P_H +#define QFONTENGINE_S60_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include "qconfig.h" +#include "qfontengine_p.h" +#include "qsize.h" +#include <OPENFONT.H> + +class CFbsBitmap; +class CFbsBitmapDevice; +class CFbsBitGc; +class CFont; + +QT_BEGIN_NAMESPACE + +// ..gives us access to truetype tables, UTF-16<->GlyphID mapping, and glyph outlines +class QFontEngineS60Extensions +{ +public: + QFontEngineS60Extensions(CFont* fontOwner, COpenFont *font); + + QByteArray getSfntTable(uint tag) const; + const unsigned char *cmap() const; + QPainterPath glyphOutline(glyph_t glyph) const; + CFont *fontOwner() const; + +private: + COpenFont *m_font; + const MOpenFontShapingExtension *m_shapingExtension; + mutable MOpenFontTrueTypeExtension *m_trueTypeExtension; + mutable const unsigned char *m_cmap; + mutable bool m_symbolCMap; + mutable QByteArray m_cmapTable; + CFont* m_fontOwner; +}; + +class QFontEngineS60 : public QFontEngine +{ +public: + QFontEngineS60(const QFontDef &fontDef, const QFontEngineS60Extensions *extensions); + ~QFontEngineS60(); + + bool stringToCMap(const QChar *str, int len, QGlyphLayout *glyphs, int *nglyphs, QTextEngine::ShaperFlags flags) const; + void recalcAdvances(QGlyphLayout *glyphs, QTextEngine::ShaperFlags flags) const; + + QImage alphaMapForGlyph(glyph_t glyph); + + glyph_metrics_t boundingBox(const QGlyphLayout &glyphs); + glyph_metrics_t boundingBox_const(glyph_t glyph) const; // Const correctnes quirk. + glyph_metrics_t boundingBox(glyph_t glyph); + + QFixed ascent() const; + QFixed descent() const; + QFixed leading() const; + qreal maxCharWidth() const; + qreal minLeftBearing() const { return 0; } + qreal minRightBearing() const { return 0; } + + QByteArray getSfntTable(uint tag) const; + + static qreal pixelsToPoints(qreal pixels, Qt::Orientation orientation = Qt::Horizontal); + static qreal pointsToPixels(qreal points, Qt::Orientation orientation = Qt::Horizontal); + + const char *name() const; + + bool canRender(const QChar *string, int len); + + Type type() const; + +private: + friend class QFontPrivate; + + QFixed glyphAdvance(HB_Glyph glyph) const; + void getCharacterData(glyph_t glyph, TOpenFontCharMetrics& metrics, const TUint8*& bitmap, TSize& bitmapSize) const; + + CFbsBitmap *m_textRenderBitmap; + CFbsBitmapDevice *m_textRenderBitmapDevice; + CFbsBitGc *m_textRenderBitmapGc; + CFont* m_font; + const QFontEngineS60Extensions *m_extensions; + qreal m_fontSizeInPixels; +}; + +class QFontEngineMultiS60 : public QFontEngineMulti +{ +public: + QFontEngineMultiS60(QFontEngine *first, int script, const QStringList &fallbackFamilies); + void loadEngine(int at); + + int m_script; + QStringList m_fallbackFamilies; +}; + +QT_END_NAMESPACE + +#endif // QFONTENGINE_S60_P_H diff --git a/src/gui/text/qfontengine_win.cpp b/src/gui/text/qfontengine_win.cpp index b165188..19c17ae 100644 --- a/src/gui/text/qfontengine_win.cpp +++ b/src/gui/text/qfontengine_win.cpp @@ -1,7 +1,6 @@ /**************************************************************************** ** ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** ** This file is part of the QtGui module of the Qt Toolkit. @@ -21,9 +20,10 @@ ** ensure the GNU Lesser General Public License version 2.1 requirements ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. ** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.1, included in the file LGPL_EXCEPTION.txt in this +** package. ** ** If you have questions regarding the use of this file, please contact ** Nokia at qt-info@nokia.com. @@ -48,7 +48,6 @@ #include <qlibrary.h> #include <qpaintdevice.h> #include <qpainter.h> -#include <qlibrary.h> #include <limits.h> #include <qendian.h> @@ -65,7 +64,7 @@ #include <private/qpaintengine_raster_p.h> #include <private/qnativeimage_p.h> -#if defined(Q_OS_WINCE) +#if defined(Q_WS_WINCE) #include "qguifunctions_wince.h" #endif @@ -85,8 +84,6 @@ ((quint32)(ch1)) \ ) -typedef BOOL (WINAPI *PtrGetCharWidthI)(HDC, UINT, UINT, LPWORD, LPINT); - // common DC for all fonts QT_BEGIN_NAMESPACE @@ -128,8 +125,7 @@ HDC shared_dc() } #endif -static HFONT stock_sysfont = 0; - +typedef BOOL (WINAPI *PtrGetCharWidthI)(HDC, UINT, UINT, LPWORD, LPINT); static PtrGetCharWidthI ptrGetCharWidthI = 0; static bool resolvedGetCharWidthI = false; @@ -141,27 +137,6 @@ static void resolveGetCharWidthI() ptrGetCharWidthI = (PtrGetCharWidthI)QLibrary::resolve(QLatin1String("gdi32"), "GetCharWidthI"); } -// Copy a LOGFONTW struct into a LOGFONTA by converting the face name to an 8 bit value. -// This is needed when calling CreateFontIndirect on non-unicode windowses. -inline static void wa_copy_logfont(LOGFONTW *lfw, LOGFONTA *lfa) -{ - lfa->lfHeight = lfw->lfHeight; - lfa->lfWidth = lfw->lfWidth; - lfa->lfEscapement = lfw->lfEscapement; - lfa->lfOrientation = lfw->lfOrientation; - lfa->lfWeight = lfw->lfWeight; - lfa->lfItalic = lfw->lfItalic; - lfa->lfUnderline = lfw->lfUnderline; - lfa->lfCharSet = lfw->lfCharSet; - lfa->lfOutPrecision = lfw->lfOutPrecision; - lfa->lfClipPrecision = lfw->lfClipPrecision; - lfa->lfQuality = lfw->lfQuality; - lfa->lfPitchAndFamily = lfw->lfPitchAndFamily; - - QString fam = QString::fromUtf16((const ushort*)lfw->lfFaceName); - memcpy(lfa->lfFaceName, fam.toLocal8Bit().constData(), fam.length() + 1); -} - // defined in qtextengine_win.cpp typedef void *SCRIPT_CACHE; typedef HRESULT (WINAPI *fScriptFreeCache)(SCRIPT_CACHE *); @@ -187,14 +162,6 @@ static inline quint16 getUShort(unsigned char *p) return val; } -static inline HFONT systemFont() -{ - if (stock_sysfont == 0) - stock_sysfont = (HFONT)GetStockObject(SYSTEM_FONT); - return stock_sysfont; -} - - // general font engine QFixed QFontEngineWin::lineThickness() const @@ -205,33 +172,18 @@ QFixed QFontEngineWin::lineThickness() const return QFontEngine::lineThickness(); } -#if defined(Q_OS_WINCE) -static OUTLINETEXTMETRICW *getOutlineTextMetric(HDC hdc) -{ - int size; - size = GetOutlineTextMetricsW(hdc, 0, 0); - OUTLINETEXTMETRICW *otm = (OUTLINETEXTMETRICW *)malloc(size); - GetOutlineTextMetricsW(hdc, size, otm); - return otm; -} -#else -static OUTLINETEXTMETRICA *getOutlineTextMetric(HDC hdc) +static OUTLINETEXTMETRIC *getOutlineTextMetric(HDC hdc) { int size; - size = GetOutlineTextMetricsA(hdc, 0, 0); - OUTLINETEXTMETRICA *otm = (OUTLINETEXTMETRICA *)malloc(size); - GetOutlineTextMetricsA(hdc, size, otm); + size = GetOutlineTextMetrics(hdc, 0, 0); + OUTLINETEXTMETRIC *otm = (OUTLINETEXTMETRIC *)malloc(size); + GetOutlineTextMetrics(hdc, size, otm); return otm; } -#endif void QFontEngineWin::getCMap() { - QT_WA({ - ttf = (bool)(tm.w.tmPitchAndFamily & TMPF_TRUETYPE); - } , { - ttf = (bool)(tm.a.tmPitchAndFamily & TMPF_TRUETYPE); - }); + ttf = (bool)(tm.tmPitchAndFamily & TMPF_TRUETYPE); HDC hdc = shared_dc(); SelectObject(hdc, hfont); bool symb = false; @@ -249,11 +201,7 @@ void QFontEngineWin::getCMap() designToDevice = 1; _faceId.index = 0; if(cmap) { -#if defined(Q_OS_WINCE) - OUTLINETEXTMETRICW *otm = getOutlineTextMetric(hdc); -#else - OUTLINETEXTMETRICA *otm = getOutlineTextMetric(hdc); -#endif + OUTLINETEXTMETRIC *otm = getOutlineTextMetric(hdc); designToDevice = QFixed((int)otm->otmEMSquare)/int(otm->otmTextMetrics.tmHeight); unitsPerEm = otm->otmEMSquare; x_height = (int)otm->otmsXHeight; @@ -263,7 +211,7 @@ void QFontEngineWin::getCMap() fsType = otm->otmfsType; free(otm); } else { - unitsPerEm = tm.w.tmHeight; + unitsPerEm = tm.tmHeight; } } @@ -286,7 +234,7 @@ int QFontEngineWin::getGlyphIndexes(const QChar *str, int numChars, QGlyphLayout int i = 0; int glyph_pos = 0; if (mirrored) { -#if defined(Q_OS_WINCE) +#if defined(Q_WS_WINCE) { #else if (symbol) { @@ -303,19 +251,14 @@ int QFontEngineWin::getGlyphIndexes(const QChar *str, int numChars, QGlyphLayout } } else { #endif - ushort first, last; - QT_WA({ - first = tm.w.tmFirstChar; - last = tm.w.tmLastChar; - }, { - first = tm.a.tmFirstChar; - last = tm.a.tmLastChar; - }); + wchar_t first = tm.tmFirstChar; + wchar_t last = tm.tmLastChar; + for (; i < numChars; ++i, ++glyph_pos) { uint ucs = QChar::mirroredChar(getChar(str, i, numChars)); if ( -#ifdef Q_OS_WINCE - tm.w.tmFirstChar > 60000 || // see line 375 +#ifdef Q_WS_WINCE + tm.tmFirstChar > 60000 || // see line 375 #endif ucs >= first && ucs <= last) glyphs->glyphs[glyph_pos] = ucs; @@ -324,7 +267,7 @@ int QFontEngineWin::getGlyphIndexes(const QChar *str, int numChars, QGlyphLayout } } } else { -#if defined(Q_OS_WINCE) +#if defined(Q_WS_WINCE) { #else if (symbol) { @@ -341,19 +284,14 @@ int QFontEngineWin::getGlyphIndexes(const QChar *str, int numChars, QGlyphLayout } } else { #endif - ushort first, last; - QT_WA({ - first = tm.w.tmFirstChar; - last = tm.w.tmLastChar; - }, { - first = tm.a.tmFirstChar; - last = tm.a.tmLastChar; - }); + wchar_t first = tm.tmFirstChar; + wchar_t last = tm.tmLastChar; + for (; i < numChars; ++i, ++glyph_pos) { uint uc = getChar(str, i, numChars); if ( -#ifdef Q_OS_WINCE - tm.w.tmFirstChar > 60000 || // see comment in QFontEngineWin +#ifdef Q_WS_WINCE + tm.tmFirstChar > 60000 || // see comment in QFontEngineWin #endif uc >= first && uc <= last) glyphs->glyphs[glyph_pos] = uc; @@ -387,28 +325,16 @@ QFontEngineWin::QFontEngineWin(const QString &name, HFONT _hfont, bool stockFont lineWidth = -1; x_height = -1; - BOOL res; - QT_WA({ - res = GetTextMetricsW(hdc, &tm.w); - } , { - res = GetTextMetricsA(hdc, &tm.a); - }); - fontDef.fixedPitch = !(tm.w.tmPitchAndFamily & TMPF_FIXED_PITCH); - if (!res) + BOOL res = GetTextMetrics(hdc, &tm); + fontDef.fixedPitch = !(tm.tmPitchAndFamily & TMPF_FIXED_PITCH); + if (!res) { qErrnoWarning("QFontEngineWin: GetTextMetrics failed"); + ZeroMemory(&tm, sizeof(TEXTMETRIC)); + } - cache_cost = tm.w.tmHeight * tm.w.tmAveCharWidth * 2000; + cache_cost = tm.tmHeight * tm.tmAveCharWidth * 2000; getCMap(); - useTextOutA = false; -#ifndef Q_OS_WINCE - // TextOutW doesn't work for symbol fonts on Windows 95! - // since we're using glyph indices we don't care for ttfs about this! - if (QSysInfo::WindowsVersion == QSysInfo::WV_95 && !ttf && - (_name == QLatin1String("Marlett") || _name == QLatin1String("Symbol") || - _name == QLatin1String("Webdings") || _name == QLatin1String("Wingdings"))) - useTextOutA = true; -#endif widthCache = 0; widthCacheSize = 0; designAdvances = 0; @@ -427,7 +353,7 @@ QFontEngineWin::~QFontEngineWin() free(widthCache); // make sure we aren't by accident still selected - SelectObject(shared_dc(), systemFont()); + SelectObject(shared_dc(), (HFONT)GetStockObject(SYSTEM_FONT)); if (!stockFont) { if (!DeleteObject(hfont)) @@ -435,39 +361,12 @@ QFontEngineWin::~QFontEngineWin() } } -HGDIOBJ QFontEngineWin::selectDesignFont(QFixed *overhang) const +HGDIOBJ QFontEngineWin::selectDesignFont() const { LOGFONT f = logfont; f.lfHeight = unitsPerEm; - HFONT designFont; - QT_WA({ - designFont = CreateFontIndirectW(&f); - }, { - LOGFONTA fa; - wa_copy_logfont(&f, &fa); - designFont = CreateFontIndirectA(&fa); - }); - HGDIOBJ oldFont = SelectObject(shared_dc(), designFont); - - if (QSysInfo::WindowsVersion & QSysInfo::WV_DOS_based) { - BOOL res; - QT_WA({ - TEXTMETRICW tm; - res = GetTextMetricsW(shared_dc(), &tm); - if (!res) - qErrnoWarning("QFontEngineWin: GetTextMetrics failed"); - *overhang = QFixed((int)tm.tmOverhang) / designToDevice; - } , { - TEXTMETRICA tm; - res = GetTextMetricsA(shared_dc(), &tm); - if (!res) - qErrnoWarning("QFontEngineWin: GetTextMetrics failed"); - *overhang = QFixed((int)tm.tmOverhang) / designToDevice; - }); - } else { - *overhang = 0; - } - return oldFont; + HFONT designFont = CreateFontIndirect(&f); + return SelectObject(shared_dc(), designFont); } bool QFontEngineWin::stringToCMap(const QChar *str, int len, QGlyphLayout *glyphs, int *nglyphs, QTextEngine::ShaperFlags flags) const @@ -482,12 +381,10 @@ bool QFontEngineWin::stringToCMap(const QChar *str, int len, QGlyphLayout *glyph if (flags & QTextEngine::GlyphIndicesOnly) return true; -#if defined(Q_OS_WINCE) +#if defined(Q_WS_WINCE) HDC hdc = shared_dc(); if (flags & QTextEngine::DesignMetrics) { HGDIOBJ oldFont = 0; - QFixed overhang = 0; - int glyph_pos = 0; for(register int i = 0; i < len; i++) { bool surrogate = (str[i].unicode() >= 0xd800 && str[i].unicode() < 0xdc00 && i < len-1 @@ -495,16 +392,16 @@ bool QFontEngineWin::stringToCMap(const QChar *str, int len, QGlyphLayout *glyph unsigned int glyph = glyphs->glyphs[glyph_pos]; if(int(glyph) >= designAdvancesSize) { int newSize = (glyph + 256) >> 8 << 8; - designAdvances = (QFixed *)realloc(designAdvances, newSize*sizeof(QFixed)); + designAdvances = q_check_ptr((QFixed *)realloc(designAdvances, newSize*sizeof(QFixed))); for(int i = designAdvancesSize; i < newSize; ++i) designAdvances[i] = -1000000; designAdvancesSize = newSize; } if(designAdvances[glyph] < -999999) { if(!oldFont) - oldFont = selectDesignFont(&overhang); + oldFont = selectDesignFont(); SIZE size = {0, 0}; - GetTextExtentPoint32W(hdc, (wchar_t *)(str+i), surrogate ? 2 : 1, &size); + GetTextExtentPoint32(hdc, (wchar_t *)(str+i), surrogate ? 2 : 1, &size); designAdvances[glyph] = QFixed((int)size.cx)/designToDevice; } glyphs->advances_x[glyph_pos] = designAdvances[glyph]; @@ -528,7 +425,8 @@ bool QFontEngineWin::stringToCMap(const QChar *str, int len, QGlyphLayout *glyph if (glyph >= widthCacheSize) { int newSize = (glyph + 256) >> 8 << 8; - widthCache = (unsigned char *)realloc(widthCache, newSize*sizeof(QFixed)); + widthCache = q_check_ptr((unsigned char *)realloc(widthCache, + newSize*sizeof(QFixed))); memset(widthCache + widthCacheSize, 0, newSize - widthCacheSize); widthCacheSize = newSize; } @@ -538,7 +436,7 @@ bool QFontEngineWin::stringToCMap(const QChar *str, int len, QGlyphLayout *glyph SIZE size = {0, 0}; if (!oldFont) oldFont = SelectObject(hdc, hfont); - GetTextExtentPoint32W(hdc, (wchar_t *)str + i, surrogate ? 2 : 1, &size); + GetTextExtentPoint32(hdc, (wchar_t *)str + i, surrogate ? 2 : 1, &size); glyphs->advances_x[glyph_pos] = size.cx; // if glyph's within cache range, store it for later if (size.cx > 0 && size.cx < 0x100) @@ -564,46 +462,24 @@ void QFontEngineWin::recalcAdvances(QGlyphLayout *glyphs, QTextEngine::ShaperFla HGDIOBJ oldFont = 0; HDC hdc = shared_dc(); if (ttf && (flags & QTextEngine::DesignMetrics)) { - QFixed overhang = 0; - for(int i = 0; i < glyphs->numGlyphs; i++) { unsigned int glyph = glyphs->glyphs[i]; if(int(glyph) >= designAdvancesSize) { int newSize = (glyph + 256) >> 8 << 8; - designAdvances = (QFixed *)realloc(designAdvances, newSize*sizeof(QFixed)); + designAdvances = q_check_ptr((QFixed *)realloc(designAdvances, + newSize*sizeof(QFixed))); for(int i = designAdvancesSize; i < newSize; ++i) designAdvances[i] = -1000000; designAdvancesSize = newSize; } - if(designAdvances[glyph] < -999999) { - if(!oldFont) - oldFont = selectDesignFont(&overhang); + if (designAdvances[glyph] < -999999) { + if (!oldFont) + oldFont = selectDesignFont(); - if (ptrGetCharWidthI) { - int width = 0; + int width = 0; + if (ptrGetCharWidthI) ptrGetCharWidthI(hdc, glyph, 1, 0, &width); - - designAdvances[glyph] = QFixed(width) / designToDevice; - } else { -#ifndef Q_OS_WINCE - GLYPHMETRICS gm; - DWORD res = GDI_ERROR; - MAT2 mat; - mat.eM11.value = mat.eM22.value = 1; - mat.eM11.fract = mat.eM22.fract = 0; - mat.eM21.value = mat.eM12.value = 0; - mat.eM21.fract = mat.eM12.fract = 0; - QT_WA({ - res = GetGlyphOutlineW(hdc, glyph, GGO_METRICS|GGO_GLYPH_INDEX|GGO_NATIVE, &gm, 0, 0, &mat); - } , { - res = GetGlyphOutlineA(hdc, glyph, GGO_METRICS|GGO_GLYPH_INDEX|GGO_NATIVE, &gm, 0, 0, &mat); - }); - - if (res != GDI_ERROR) { - designAdvances[glyph] = QFixed(gm.gmCellIncX) / designToDevice; - } -#endif - } + designAdvances[glyph] = QFixed(width) / designToDevice; } glyphs->advances_x[i] = designAdvances[glyph]; glyphs->advances_y[i] = 0; @@ -611,8 +487,6 @@ void QFontEngineWin::recalcAdvances(QGlyphLayout *glyphs, QTextEngine::ShaperFla if(oldFont) DeleteObject(SelectObject(hdc, oldFont)); } else { - int overhang = (QSysInfo::WindowsVersion & QSysInfo::WV_DOS_based) ? tm.a.tmOverhang : 0; - for(int i = 0; i < glyphs->numGlyphs; i++) { unsigned int glyph = glyphs->glyphs[i]; @@ -620,7 +494,8 @@ void QFontEngineWin::recalcAdvances(QGlyphLayout *glyphs, QTextEngine::ShaperFla if (glyph >= widthCacheSize) { int newSize = (glyph + 256) >> 8 << 8; - widthCache = (unsigned char *)realloc(widthCache, newSize*sizeof(QFixed)); + widthCache = q_check_ptr((unsigned char *)realloc(widthCache, + newSize*sizeof(QFixed))); memset(widthCache + widthCacheSize, 0, newSize - widthCacheSize); widthCacheSize = newSize; } @@ -640,31 +515,10 @@ void QFontEngineWin::recalcAdvances(QGlyphLayout *glyphs, QTextEngine::ShaperFla ++chrLen; } SIZE size = {0, 0}; - GetTextExtentPoint32W(hdc, (wchar_t *)ch, chrLen, &size); + GetTextExtentPoint32(hdc, (wchar_t *)ch, chrLen, &size); width = size.cx; } else if (ptrGetCharWidthI) { ptrGetCharWidthI(hdc, glyph, 1, 0, &width); - - width -= overhang; - } else { -#ifndef Q_OS_WINCE - GLYPHMETRICS gm; - DWORD res = GDI_ERROR; - MAT2 mat; - mat.eM11.value = mat.eM22.value = 1; - mat.eM11.fract = mat.eM22.fract = 0; - mat.eM21.value = mat.eM12.value = 0; - mat.eM21.fract = mat.eM12.fract = 0; - QT_WA({ - res = GetGlyphOutlineW(hdc, glyph, GGO_METRICS|GGO_GLYPH_INDEX, &gm, 0, 0, &mat); - } , { - res = GetGlyphOutlineA(hdc, glyph, GGO_METRICS|GGO_GLYPH_INDEX, &gm, 0, 0, &mat); - }); - - if (res != GDI_ERROR) { - width = gm.gmCellIncX; - } -#endif } glyphs->advances_x[i] = width; // if glyph's within cache range, store it for later @@ -687,48 +541,24 @@ glyph_metrics_t QFontEngineWin::boundingBox(const QGlyphLayout &glyphs) for (int i = 0; i < glyphs.numGlyphs; ++i) w += glyphs.effectiveAdvance(i); - return glyph_metrics_t(0, -tm.w.tmAscent, w, tm.w.tmHeight, w, 0); + return glyph_metrics_t(0, -tm.tmAscent, w, tm.tmHeight, w, 0); } - - -#ifndef Q_OS_WINCE -typedef HRESULT (WINAPI *pGetCharABCWidthsFloat)(HDC, UINT, UINT, LPABCFLOAT); -static pGetCharABCWidthsFloat qt_GetCharABCWidthsFloat = 0; -#endif - glyph_metrics_t QFontEngineWin::boundingBox(glyph_t glyph, const QTransform &t) { -#ifndef Q_OS_WINCE +#ifndef Q_WS_WINCE GLYPHMETRICS gm; HDC hdc = shared_dc(); SelectObject(hdc, hfont); - if(!ttf) { - SIZE s = {0, 0}; - WCHAR ch = glyph; - int width; - int overhang = 0; - static bool resolved = false; - if (!resolved) { - QLibrary lib(QLatin1String("gdi32")); - qt_GetCharABCWidthsFloat = (pGetCharABCWidthsFloat) lib.resolve("GetCharABCWidthsFloatW"); - resolved = true; - } - if (QT_WA_INLINE(true, false) && qt_GetCharABCWidthsFloat) { - ABCFLOAT abc; - qt_GetCharABCWidthsFloat(hdc, ch, ch, &abc); - width = qRound(abc.abcfB); - } else { - GetTextExtentPoint32W(hdc, &ch, 1, &s); - overhang = (QSysInfo::WindowsVersion & QSysInfo::WV_DOS_based) ? tm.a.tmOverhang : 0; - width = s.cx; - } + if (!ttf) { + wchar_t ch = glyph; + ABCFLOAT abc; + GetCharABCWidthsFloat(hdc, ch, ch, &abc); + int width = qRound(abc.abcfB); - return glyph_metrics_t(0, -tm.a.tmAscent, - width, tm.a.tmHeight, - width-overhang, 0).transformed(t); + return glyph_metrics_t(0, -tm.tmAscent, width, tm.tmHeight, width, 0).transformed(t); } else { DWORD res = 0; MAT2 mat; @@ -753,11 +583,8 @@ glyph_metrics_t QFontEngineWin::boundingBox(glyph_t glyph, const QTransform &t) SetWorldTransform(hdc, &xform); } - QT_WA({ - res = GetGlyphOutlineW(hdc, glyph, GGO_METRICS|GGO_GLYPH_INDEX, &gm, 0, 0, &mat); - } , { - res = GetGlyphOutlineA(hdc, glyph, GGO_METRICS|GGO_GLYPH_INDEX, &gm, 0, 0, &mat); - }); + res = GetGlyphOutline(hdc, glyph, GGO_METRICS | GGO_GLYPH_INDEX, &gm, 0, 0, &mat); + if (t.type() > QTransform::TxTranslate) { XFORM xform; xform.eM11 = xform.eM22 = 1; @@ -793,28 +620,28 @@ glyph_metrics_t QFontEngineWin::boundingBox(glyph_t glyph, const QTransform &t) else #endif { // fallback - width = tm.w.tmMaxCharWidth; + width = tm.tmMaxCharWidth; advance = width; } SelectObject(hdc, oldFont); - return glyph_metrics_t(0, -tm.w.tmAscent, width, tm.w.tmHeight, advance, 0).transformed(t); + return glyph_metrics_t(0, -tm.tmAscent, width, tm.tmHeight, advance, 0).transformed(t); #endif } QFixed QFontEngineWin::ascent() const { - return tm.w.tmAscent; + return tm.tmAscent; } QFixed QFontEngineWin::descent() const { - return tm.w.tmDescent; + return tm.tmDescent; } QFixed QFontEngineWin::leading() const { - return tm.w.tmExternalLeading; + return tm.tmExternalLeading; } @@ -827,12 +654,12 @@ QFixed QFontEngineWin::xHeight() const QFixed QFontEngineWin::averageCharWidth() const { - return tm.w.tmAveCharWidth; + return tm.tmAveCharWidth; } qreal QFontEngineWin::maxCharWidth() const { - return tm.w.tmMaxCharWidth; + return tm.tmMaxCharWidth; } enum { max_font_count = 256 }; @@ -871,7 +698,7 @@ qreal QFontEngineWin::minLeftBearing() const qreal QFontEngineWin::minRightBearing() const { -#ifdef Q_OS_WINCE +#ifdef Q_WS_WINCE if (rbearing == SHRT_MIN) { int ml = 0; int mr = 0; @@ -879,10 +706,10 @@ qreal QFontEngineWin::minRightBearing() const SelectObject(hdc, hfont); if (ttf) { ABC *abc = 0; - int n = QT_WA_INLINE(tm.w.tmLastChar - tm.w.tmFirstChar, tm.a.tmLastChar - tm.a.tmFirstChar); + int n = tm.tmLastChar - tm.tmFirstChar; if (n <= max_font_count) { abc = new ABC[n+1]; - GetCharABCWidths(hdc, tm.w.tmFirstChar, tm.w.tmLastChar, abc); + GetCharABCWidths(hdc, tm.tmFirstChar, tm.tmLastChar, abc); } else { abc = new ABC[char_table_entries+1]; for(int i = 0; i < char_table_entries; i++) @@ -898,9 +725,6 @@ qreal QFontEngineWin::minRightBearing() const } } delete [] abc; - } else { - ml = 0; - mr = -tm.a.tmOverhang; } lbearing = ml; rbearing = mr; @@ -915,28 +739,14 @@ qreal QFontEngineWin::minRightBearing() const SelectObject(hdc, hfont); if (ttf) { ABC *abc = 0; - int n = QT_WA_INLINE(tm.w.tmLastChar - tm.w.tmFirstChar, tm.a.tmLastChar - tm.a.tmFirstChar); + int n = tm.tmLastChar - tm.tmFirstChar; if (n <= max_font_count) { abc = new ABC[n+1]; - QT_WA({ - GetCharABCWidths(hdc, tm.w.tmFirstChar, tm.w.tmLastChar, abc); - }, { - GetCharABCWidthsA(hdc,tm.a.tmFirstChar,tm.a.tmLastChar,abc); - }); + GetCharABCWidths(hdc, tm.tmFirstChar, tm.tmLastChar, abc); } else { abc = new ABC[char_table_entries+1]; - QT_WA({ - for(int i = 0; i < char_table_entries; i++) - GetCharABCWidths(hdc, char_table[i], char_table[i], abc+i); - }, { - for(int i = 0; i < char_table_entries; i++) { - QByteArray w = QString(QChar(char_table[i])).toLocal8Bit(); - if (w.length() == 1) { - uint ch8 = (uchar)w[0]; - GetCharABCWidthsA(hdc, ch8, ch8, abc+i); - } - } - }); + for(int i = 0; i < char_table_entries; i++) + GetCharABCWidths(hdc, char_table[i], char_table[i], abc + i); n = char_table_entries; } ml = abc[0].abcA; @@ -949,33 +759,28 @@ qreal QFontEngineWin::minRightBearing() const } delete [] abc; } else { - QT_WA({ - ABCFLOAT *abc = 0; - int n = tm.w.tmLastChar - tm.w.tmFirstChar+1; - if (n <= max_font_count) { - abc = new ABCFLOAT[n]; - GetCharABCWidthsFloat(hdc, tm.w.tmFirstChar, tm.w.tmLastChar, abc); - } else { - abc = new ABCFLOAT[char_table_entries]; - for(int i = 0; i < char_table_entries; i++) - GetCharABCWidthsFloat(hdc, char_table[i], char_table[i], abc+i); - n = char_table_entries; - } - float fml = abc[0].abcfA; - float fmr = abc[0].abcfC; - for (int i=1; i<n; i++) { - if (abc[i].abcfA + abc[i].abcfB + abc[i].abcfC != 0) { - fml = qMin(fml,abc[i].abcfA); - fmr = qMin(fmr,abc[i].abcfC); - } + ABCFLOAT *abc = 0; + int n = tm.tmLastChar - tm.tmFirstChar+1; + if (n <= max_font_count) { + abc = new ABCFLOAT[n]; + GetCharABCWidthsFloat(hdc, tm.tmFirstChar, tm.tmLastChar, abc); + } else { + abc = new ABCFLOAT[char_table_entries]; + for(int i = 0; i < char_table_entries; i++) + GetCharABCWidthsFloat(hdc, char_table[i], char_table[i], abc+i); + n = char_table_entries; + } + float fml = abc[0].abcfA; + float fmr = abc[0].abcfC; + for (int i=1; i<n; i++) { + if (abc[i].abcfA + abc[i].abcfB + abc[i].abcfC != 0) { + fml = qMin(fml,abc[i].abcfA); + fmr = qMin(fmr,abc[i].abcfC); } - ml = int(fml-0.9999); - mr = int(fmr-0.9999); - delete [] abc; - } , { - ml = 0; - mr = -tm.a.tmOverhang; - }); + } + ml = int(fml - 0.9999); + mr = int(fmr - 0.9999); + delete [] abc; } lbearing = ml; rbearing = mr; @@ -1012,17 +817,10 @@ bool QFontEngineWin::canRender(const QChar *string, int len) return false; } } else { - QT_WA({ - while(len--) { - if (tm.w.tmFirstChar > string->unicode() || tm.w.tmLastChar < string->unicode()) - return false; - } - }, { - while(len--) { - if (tm.a.tmFirstChar > string->unicode() || tm.a.tmLastChar < string->unicode()) - return false; - } - }); + while(len--) { + if (tm.tmFirstChar > string->unicode() || tm.tmLastChar < string->unicode()) + return false; + } } return true; } @@ -1047,7 +845,7 @@ static inline QPointF qt_to_qpointf(const POINTFX &pt, qreal scale) { static bool addGlyphToPath(glyph_t glyph, const QFixedPoint &position, HDC hdc, QPainterPath *path, bool ttf, glyph_metrics_t *metric = 0, qreal scale = 1) { -#if defined(Q_OS_WINCE) +#if defined(Q_WS_WINCE) Q_UNUSED(glyph); Q_UNUSED(hdc); #endif @@ -1064,12 +862,8 @@ static bool addGlyphToPath(glyph_t glyph, const QFixedPoint &position, HDC hdc, GLYPHMETRICS gMetric; memset(&gMetric, 0, sizeof(GLYPHMETRICS)); int bufferSize = GDI_ERROR; -#if !defined(Q_OS_WINCE) - QT_WA( { - bufferSize = GetGlyphOutlineW(hdc, glyph, glyphFormat, &gMetric, 0, 0, &mat); - }, { - bufferSize = GetGlyphOutlineA(hdc, glyph, glyphFormat, &gMetric, 0, 0, &mat); - }); +#if !defined(Q_WS_WINCE) + bufferSize = GetGlyphOutline(hdc, glyph, glyphFormat, &gMetric, 0, 0, &mat); #endif if ((DWORD)bufferSize == GDI_ERROR) { return false; @@ -1077,14 +871,8 @@ static bool addGlyphToPath(glyph_t glyph, const QFixedPoint &position, HDC hdc, void *dataBuffer = new char[bufferSize]; DWORD ret = GDI_ERROR; -#if !defined(Q_OS_WINCE) - QT_WA( { - ret = GetGlyphOutlineW(hdc, glyph, glyphFormat, &gMetric, bufferSize, - dataBuffer, &mat); - }, { - ret = GetGlyphOutlineA(hdc, glyph, glyphFormat, &gMetric, bufferSize, - dataBuffer, &mat); - } ); +#if !defined(Q_WS_WINCE) + ret = GetGlyphOutline(hdc, glyph, glyphFormat, &gMetric, bufferSize, dataBuffer, &mat); #endif if (ret == GDI_ERROR) { delete [](char *)dataBuffer; @@ -1171,14 +959,7 @@ void QFontEngineWin::addGlyphsToPath(glyph_t *glyphs, QFixedPoint *positions, in // font at the correct pixel size. lf.lfHeight = -unitsPerEm; lf.lfWidth = 0; - HFONT hf; - QT_WA({ - hf = CreateFontIndirectW(&lf); - }, { - LOGFONTA lfa; - wa_copy_logfont(&lf, &lfa); - hf = CreateFontIndirectA(&lfa); - }); + HFONT hf = CreateFontIndirect(&lf); HDC hdc = shared_dc(); HGDIOBJ oldfont = SelectObject(hdc, hf); @@ -1199,8 +980,8 @@ void QFontEngineWin::addGlyphsToPath(glyph_t *glyphs, QFixedPoint *positions, in void QFontEngineWin::addOutlineToPath(qreal x, qreal y, const QGlyphLayout &glyphs, QPainterPath *path, QTextItem::RenderFlags flags) { -#if !defined(Q_OS_WINCE) - if(tm.w.tmPitchAndFamily & (TMPF_TRUETYPE | TMPF_VECTOR)) { +#if !defined(Q_WS_WINCE) + if(tm.tmPitchAndFamily & (TMPF_TRUETYPE | TMPF_VECTOR)) { hasOutline = true; QFontEngine::addOutlineToPath(x, y, glyphs, path, flags); if (hasOutline) { @@ -1234,11 +1015,11 @@ int QFontEngineWin::synthesized() const uchar data[4]; GetFontData(hdc, HEAD, 44, &data, 4); USHORT macStyle = getUShort(data); - if (tm.w.tmItalic && !(macStyle & 2)) + if (tm.tmItalic && !(macStyle & 2)) synthesized_flags = SynthesizedItalic; if (fontDef.stretch != 100 && ttf) synthesized_flags |= SynthesizedStretch; - if (tm.w.tmWeight >= 500 && !(macStyle & 1)) + if (tm.tmWeight >= 500 && !(macStyle & 1)) synthesized_flags |= SynthesizedBold; //qDebug() << "font is" << _name << // "it=" << (macStyle & 2) << fontDef.style << "flags=" << synthesized_flags; @@ -1254,24 +1035,12 @@ QFixed QFontEngineWin::emSquareSize() const QFontEngine::Properties QFontEngineWin::properties() const { - LOGFONT lf = logfont; lf.lfHeight = unitsPerEm; - HFONT hf; - QT_WA({ - hf = CreateFontIndirectW(&lf); - }, { - LOGFONTA lfa; - wa_copy_logfont(&lf, &lfa); - hf = CreateFontIndirectA(&lfa); - }); + HFONT hf = CreateFontIndirect(&lf); HDC hdc = shared_dc(); HGDIOBJ oldfont = SelectObject(hdc, hf); -#if defined(Q_OS_WINCE) - OUTLINETEXTMETRICW *otm = getOutlineTextMetric(hdc); -#else - OUTLINETEXTMETRICA *otm = getOutlineTextMetric(hdc); -#endif + OUTLINETEXTMETRIC *otm = getOutlineTextMetric(hdc); Properties p; p.emSquare = unitsPerEm; p.italicAngle = otm->otmItalicAngle; @@ -1301,14 +1070,7 @@ void QFontEngineWin::getUnscaledGlyph(glyph_t glyph, QPainterPath *path, glyph_m if(flags & SynthesizedItalic) lf.lfItalic = false; lf.lfWidth = 0; - HFONT hf; - QT_WA({ - hf = CreateFontIndirectW(&lf); - }, { - LOGFONTA lfa; - wa_copy_logfont(&lf, &lfa); - hf = CreateFontIndirectA(&lfa); - }); + HFONT hf = CreateFontIndirect(&lf); HDC hdc = shared_dc(); HGDIOBJ oldfont = SelectObject(hdc, hf); QFixedPoint p; @@ -1333,10 +1095,12 @@ bool QFontEngineWin::getSfntTableData(uint tag, uchar *buffer, uint *length) con # define CLEARTYPE_QUALITY 5 #endif +extern bool qt_cleartype_enabled; QNativeImage *QFontEngineWin::drawGDIGlyph(HFONT font, glyph_t glyph, int margin, const QTransform &t, QImage::Format mask_format) { + Q_UNUSED(mask_format) glyph_metrics_t gm = boundingBox(glyph); // printf(" -> for glyph %4x\n", glyph); @@ -1351,7 +1115,7 @@ QNativeImage *QFontEngineWin::drawGDIGlyph(HFONT font, glyph_t glyph, int margin bool has_transformation = t.type() > QTransform::TxTranslate; -#ifndef Q_OS_WINCE +#ifndef Q_WS_WINCE unsigned int options = ttf ? ETO_GLYPH_INDEX : 0; XFORM xform; @@ -1376,14 +1140,7 @@ QNativeImage *QFontEngineWin::drawGDIGlyph(HFONT font, glyph_t glyph, int margin memset(&mat, 0, sizeof(mat)); mat.eM11.value = mat.eM22.value = 1; - int error = 0; - QT_WA( { - error = GetGlyphOutlineW(hdc, glyph, ggo_options, &tgm, 0, 0, &mat); - }, { - error = GetGlyphOutlineA(hdc, glyph, ggo_options, &tgm, 0, 0, &mat); - } ); - - if (error == GDI_ERROR) { + if (GetGlyphOutline(hdc, glyph, ggo_options, &tgm, 0, 0, &mat) == GDI_ERROR) { qWarning("QWinFontEngine: unable to query transformed glyph metrics..."); return 0; } @@ -1408,7 +1165,11 @@ QNativeImage *QFontEngineWin::drawGDIGlyph(HFONT font, glyph_t glyph, int margin QNativeImage *ni = new QNativeImage(iw + 2 * margin + 4, ih + 2 * margin + 4, - mask_format, true); + QNativeImage::systemFormat(), !qt_cleartype_enabled); + + /*If cleartype is enabled we use the standard system format even on Windows CE + and not the special textbuffer format we have to use if cleartype is disabled*/ + ni->image.fill(0xffffffff); HDC hdc = ni->hdc; @@ -1425,11 +1186,11 @@ QNativeImage *QFontEngineWin::drawGDIGlyph(HFONT font, glyph_t glyph, int margin if (has_transformation) { SetGraphicsMode(hdc, GM_ADVANCED); SetWorldTransform(hdc, &xform); - ExtTextOutW(hdc, 0, 0, options, 0, (LPCWSTR) &glyph, 1, 0); + ExtTextOut(hdc, 0, 0, options, 0, (LPCWSTR) &glyph, 1, 0); } else #endif { - ExtTextOutW(hdc, -gx + margin, -gy + margin, options, 0, (LPCWSTR) &glyph, 1, 0); + ExtTextOut(hdc, -gx + margin, -gy + margin, options, 0, (LPCWSTR) &glyph, 1, 0); } SelectObject(hdc, old_font); @@ -1437,7 +1198,6 @@ QNativeImage *QFontEngineWin::drawGDIGlyph(HFONT font, glyph_t glyph, int margin } -extern bool qt_cleartype_enabled; extern uint qt_pow_gamma[256]; QImage QFontEngineWin::alphaMapForGlyph(glyph_t glyph, const QTransform &xform) @@ -1446,7 +1206,7 @@ QImage QFontEngineWin::alphaMapForGlyph(glyph_t glyph, const QTransform &xform) if (qt_cleartype_enabled) { LOGFONT lf = logfont; lf.lfQuality = ANTIALIASED_QUALITY; - font = CreateFontIndirectW(&lf); + font = CreateFontIndirect(&lf); } QImage::Format mask_format = QNativeImage::systemFormat(); #ifndef Q_OS_WINCE @@ -1553,17 +1313,9 @@ void QFontEngineMultiWin::loadEngine(int at) QString fam = fallbacks.at(at-1); LOGFONT lf = static_cast<QFontEngineWin *>(engines.at(0))->logfont; - HFONT hfont; - QT_WA({ - memcpy(lf.lfFaceName, fam.utf16(), sizeof(TCHAR)*qMin(fam.length()+1,32)); // 32 = Windows hard-coded - hfont = CreateFontIndirectW(&lf); - } , { - // LOGFONTA and LOGFONTW are binary compatible - QByteArray lname = fam.toLocal8Bit(); - memcpy(lf.lfFaceName,lname.data(), - qMin(lname.length()+1,32)); // 32 = Windows hard-coded - hfont = CreateFontIndirectA((LOGFONTA*)&lf); - }); + memcpy(lf.lfFaceName, fam.utf16(), sizeof(wchar_t) * qMin(fam.length() + 1, 32)); // 32 = Windows hard-coded + HFONT hfont = CreateFontIndirect(&lf); + bool stockFont = false; if (hfont == 0) { hfont = (HFONT)GetStockObject(ANSI_VAR_FONT); diff --git a/src/gui/text/qfontengine_win_p.h b/src/gui/text/qfontengine_win_p.h index ed73c8a..bf84dee 100644 --- a/src/gui/text/qfontengine_win_p.h +++ b/src/gui/text/qfontengine_win_p.h @@ -1,7 +1,6 @@ /**************************************************************************** ** ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** ** This file is part of the QtGui module of the Qt Toolkit. @@ -21,9 +20,10 @@ ** ensure the GNU Lesser General Public License version 2.1 requirements ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. ** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.1, included in the file LGPL_EXCEPTION.txt in this +** package. ** ** If you have questions regarding the use of this file, please contact ** Nokia at qt-info@nokia.com. @@ -80,7 +80,7 @@ public: virtual void addGlyphsToPath(glyph_t *glyphs, QFixedPoint *positions, int nglyphs, QPainterPath *path, QTextItem::RenderFlags flags); - HGDIOBJ selectDesignFont(QFixed *) const; + HGDIOBJ selectDesignFont() const; virtual glyph_metrics_t boundingBox(const QGlyphLayout &glyphs); virtual glyph_metrics_t boundingBox(glyph_t g) { return boundingBox(g, QTransform()); } @@ -109,18 +109,14 @@ public: int getGlyphIndexes(const QChar *ch, int numChars, QGlyphLayout *glyphs, bool mirrored) const; void getCMap(); - QString _name; - HFONT hfont; + QString _name; + HFONT hfont; LOGFONT logfont; - uint stockFont : 1; - uint useTextOutA : 1; - uint ttf : 1; + uint stockFont : 1; + uint ttf : 1; uint hasOutline : 1; - union { - TEXTMETRICW w; - TEXTMETRICA a; - } tm; - int lw; + TEXTMETRIC tm; + int lw; const unsigned char *cmap; QByteArray cmapTable; mutable qreal lbearing; diff --git a/src/gui/text/qfontengine_x11.cpp b/src/gui/text/qfontengine_x11.cpp index 92fc576..aff5400 100644 --- a/src/gui/text/qfontengine_x11.cpp +++ b/src/gui/text/qfontengine_x11.cpp @@ -1,7 +1,6 @@ /**************************************************************************** ** ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** ** This file is part of the QtGui module of the Qt Toolkit. @@ -21,9 +20,10 @@ ** ensure the GNU Lesser General Public License version 2.1 requirements ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. ** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.1, included in the file LGPL_EXCEPTION.txt in this +** package. ** ** If you have questions regarding the use of this file, please contact ** Nokia at qt-info@nokia.com. @@ -227,7 +227,7 @@ static QFontEngine::FaceId fontFile(const QByteArray &_xname, QFreetypeFace **fr QByteArray best_mapping; for (QStringList::ConstIterator it = fontpath.constBegin(); it != fontpath.constEnd(); ++it) { - if ((*it).left(1) != QLatin1String("/")) + if (!(*it).startsWith(QLatin1Char('/'))) continue; // not a path name, a font server QString fontmapname; int num = 0; @@ -693,9 +693,8 @@ QFontEngine::FaceId QFontEngineXLFD::faceId() const if (freetype) { const_cast<QFontEngineXLFD *>(this)->fsType = freetype->fsType(); } else { - QFontEngine::Properties properties = QFontEngine::properties(); face_id.index = 0; - face_id.filename = "-" + properties.postscriptName; + face_id.filename = '-' + QFontEngine::properties().postscriptName; } } #endif diff --git a/src/gui/text/qfontengine_x11_p.h b/src/gui/text/qfontengine_x11_p.h index 3f29c05..734aee7 100644 --- a/src/gui/text/qfontengine_x11_p.h +++ b/src/gui/text/qfontengine_x11_p.h @@ -1,7 +1,6 @@ /**************************************************************************** ** ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** ** This file is part of the QtGui module of the Qt Toolkit. @@ -21,9 +20,10 @@ ** ensure the GNU Lesser General Public License version 2.1 requirements ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. ** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.1, included in the file LGPL_EXCEPTION.txt in this +** package. ** ** If you have questions regarding the use of this file, please contact ** Nokia at qt-info@nokia.com. diff --git a/src/gui/text/qfontengineglyphcache_p.h b/src/gui/text/qfontengineglyphcache_p.h index b66075a..37e9382 100644 --- a/src/gui/text/qfontengineglyphcache_p.h +++ b/src/gui/text/qfontengineglyphcache_p.h @@ -1,7 +1,6 @@ /**************************************************************************** ** ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** ** This file is part of the QtGui module of the Qt Toolkit. @@ -21,9 +20,10 @@ ** ensure the GNU Lesser General Public License version 2.1 requirements ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. ** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.1, included in the file LGPL_EXCEPTION.txt in this +** package. ** ** If you have questions regarding the use of this file, please contact ** Nokia at qt-info@nokia.com. @@ -72,7 +72,7 @@ QT_BEGIN_NAMESPACE -class Q_GUI_EXPORT QFontEngineGlyphCache +class QFontEngineGlyphCache { public: QFontEngineGlyphCache(const QTransform &matrix) : m_transform(matrix) { } @@ -83,7 +83,7 @@ public: Raster_Mono }; - virtual ~QFontEngineGlyphCache(); + virtual ~QFontEngineGlyphCache() { } QTransform m_transform; }; diff --git a/src/gui/text/qfontinfo.h b/src/gui/text/qfontinfo.h index 335d761..d7bbd72 100644 --- a/src/gui/text/qfontinfo.h +++ b/src/gui/text/qfontinfo.h @@ -1,7 +1,6 @@ /**************************************************************************** ** ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** ** This file is part of the QtGui module of the Qt Toolkit. @@ -21,9 +20,10 @@ ** ensure the GNU Lesser General Public License version 2.1 requirements ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. ** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.1, included in the file LGPL_EXCEPTION.txt in this +** package. ** ** If you have questions regarding the use of this file, please contact ** Nokia at qt-info@nokia.com. diff --git a/src/gui/text/qfontmetrics.cpp b/src/gui/text/qfontmetrics.cpp index a96df58..c9be073 100644 --- a/src/gui/text/qfontmetrics.cpp +++ b/src/gui/text/qfontmetrics.cpp @@ -1,7 +1,6 @@ /**************************************************************************** ** ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** ** This file is part of the QtGui module of the Qt Toolkit. @@ -21,9 +20,10 @@ ** ensure the GNU Lesser General Public License version 2.1 requirements ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. ** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.1, included in the file LGPL_EXCEPTION.txt in this +** package. ** ** If you have questions regarding the use of this file, please contact ** Nokia at qt-info@nokia.com. @@ -75,9 +75,8 @@ extern int qt_defaultDpi(); \brief The QFontMetrics class provides font metrics information. - \ingroup multimedia + \ingroup painting \ingroup shared - \ingroup text QFontMetrics functions calculate the size of characters and strings for a given font. There are three ways you can create a @@ -164,7 +163,7 @@ extern int qt_defaultDpi(); metrics that are compatible with a certain paint device. */ QFontMetrics::QFontMetrics(const QFont &font) - : d(font.d) + : d(font.d.data()) { d->ref.ref(); } @@ -196,7 +195,7 @@ QFontMetrics::QFontMetrics(const QFont &font, QPaintDevice *paintdevice) d->dpi = dpi; d->screen = screen; } else { - d = font.d; + d = font.d.data(); d->ref.ref(); } @@ -528,12 +527,14 @@ int QFontMetrics::rightBearing(QChar ch) const */ int QFontMetrics::width(const QString &text, int len) const { + int pos = text.indexOf(QLatin1Char('\x9c')); + QString txt = (pos == -1) ? text : text.left(pos); if (len < 0) - len = text.length(); + len = txt.length(); if (len == 0) return 0; - QTextEngine layout(text, d); + QTextEngine layout(txt, d); layout.ignoreBidi = true; return qRound(layout.width(0, len)); } @@ -557,11 +558,10 @@ int QFontMetrics::width(const QString &text, int len) const \warning This function will produce incorrect results for Arabic characters or non-spacing marks in the middle of a string, as the glyph shaping and positioning of marks that happens when - processing strings cannot be taken into account. Use charWidth() - instead if you aren't looking for the width of isolated - characters. + processing strings cannot be taken into account. When implementing + an interactive text control, use QTextLayout instead. - \sa boundingRect(), charWidth() + \sa boundingRect() */ int QFontMetrics::width(QChar ch) const { @@ -799,7 +799,7 @@ QRect QFontMetrics::boundingRect(const QRect &rect, int flags, const QString &te */ QSize QFontMetrics::size(int flags, const QString &text, int tabStops, int *tabArray) const { - return boundingRect(QRect(0,0,0,0), flags, text, tabStops, tabArray).size(); + return boundingRect(QRect(0,0,0,0), flags | Qt::TextLongestVariant, text, tabStops, tabArray).size(); } /*! @@ -858,11 +858,23 @@ QRect QFontMetrics::tightBoundingRect(const QString &text) const right-to-left layouts, and on the left side for right-to-left layouts. Note that this behavior is independent of the text language. - */ QString QFontMetrics::elidedText(const QString &text, Qt::TextElideMode mode, int width, int flags) const { - QStackTextEngine engine(text, QFont(d)); + QString _text = text; + if (!(flags & Qt::TextLongestVariant)) { + int posA = 0; + int posB = _text.indexOf(QLatin1Char('\x9c')); + while (posB >= 0) { + QString portion = _text.mid(posA, posB - posA); + if (size(flags, portion).width() <= width) + return portion; + posA = posB + 1; + posB = _text.indexOf(QLatin1Char('\x9c'), posA); + } + _text = _text.mid(posA); + } + QStackTextEngine engine(_text, QFont(d)); return engine.elidedText(mode, width, flags); } @@ -928,9 +940,8 @@ int QFontMetrics::lineWidth() const \brief The QFontMetricsF class provides font metrics information. - \ingroup multimedia + \ingroup painting \ingroup shared - \ingroup text QFontMetricsF functions calculate the size of characters and strings for a given font. You can construct a QFontMetricsF object @@ -1006,7 +1017,7 @@ QFontMetricsF &QFontMetricsF::operator=(const QFontMetrics &other) metrics that are compatible with a certain paint device. */ QFontMetricsF::QFontMetricsF(const QFont &font) - : d(font.d) + : d(font.d.data()) { d->ref.ref(); } @@ -1038,7 +1049,7 @@ QFontMetricsF::QFontMetricsF(const QFont &font, QPaintDevice *paintdevice) d->dpi = dpi; d->screen = screen; } else { - d = font.d; + d = font.d.data(); d->ref.ref(); } @@ -1386,9 +1397,8 @@ qreal QFontMetricsF::width(const QString &text) const \warning This function will produce incorrect results for Arabic characters or non-spacing marks in the middle of a string, as the glyph shaping and positioning of marks that happens when - processing strings cannot be taken into account. Use charWidth() - instead if you aren't looking for the width of isolated - characters. + processing strings cannot be taken into account. When implementing + an interactive text control, use QTextLayout instead. \sa boundingRect() */ diff --git a/src/gui/text/qfontmetrics.h b/src/gui/text/qfontmetrics.h index 1147e3a..f7151d1 100644 --- a/src/gui/text/qfontmetrics.h +++ b/src/gui/text/qfontmetrics.h @@ -1,7 +1,6 @@ /**************************************************************************** ** ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** ** This file is part of the QtGui module of the Qt Toolkit. @@ -21,9 +20,10 @@ ** ensure the GNU Lesser General Public License version 2.1 requirements ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. ** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.1, included in the file LGPL_EXCEPTION.txt in this +** package. ** ** If you have questions regarding the use of this file, please contact ** Nokia at qt-info@nokia.com. diff --git a/src/gui/text/qfontsubset.cpp b/src/gui/text/qfontsubset.cpp index 74860b4..f542c38 100644 --- a/src/gui/text/qfontsubset.cpp +++ b/src/gui/text/qfontsubset.cpp @@ -1,7 +1,6 @@ /**************************************************************************** ** ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** ** This file is part of the QtGui module of the Qt Toolkit. @@ -21,9 +20,10 @@ ** ensure the GNU Lesser General Public License version 2.1 requirements ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. ** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.1, included in the file LGPL_EXCEPTION.txt in this +** package. ** ** If you have questions regarding the use of this file, please contact ** Nokia at qt-info@nokia.com. @@ -333,17 +333,17 @@ QByteArray QFontSubset::glyphName(unsigned int glyph, const QVector<int> reverse name[0] = 0; } if (name[0]) { - s << "/" << name; + s << '/' << name; } else #endif #if defined(Q_WS_X11) if (fontEngine->type() == QFontEngine::XLFD) { uint uc = static_cast<QFontEngineXLFD *>(fontEngine)->toUnicode(glyphIndex); - s << "/" << glyphName(uc, false /* ### */); + s << '/' << glyphName(uc, false /* ### */); } else #endif if (reverseMap[glyphIndex] && reverseMap[glyphIndex] < 0x10000) { - s << "/" << glyphName(reverseMap[glyphIndex], false); + s << '/' << glyphName(reverseMap[glyphIndex], false); } else { s << "/gl" << (int)glyphIndex; } @@ -395,13 +395,13 @@ QByteArray QFontSubset::widthArray() const int endnonlinear = startLinear ? startLinear : g; // qDebug(" startLinear=%x endnonlinear=%x", startLinear,endnonlinear); if (endnonlinear > start) { - s << start << "["; + s << start << '['; for (int i = start; i < endnonlinear; ++i) s << (widths[i]*scale).toInt(); s << "]\n"; } if (startLinear) - s << startLinear << g - 1 << (widths[startLinear]*scale).toInt() << "\n"; + s << startLinear << g - 1 << (widths[startLinear]*scale).toInt() << '\n'; } s << "]\n"; } @@ -488,14 +488,14 @@ QByteArray QFontSubset::createToUnicodeMap() const int endnonlinear = startLinear ? startLinear : g; // qDebug(" startLinear=%x endnonlinear=%x", startLinear,endnonlinear); if (endnonlinear > start) { - s << "<" << QPdf::toHex((ushort)start, buf) << "> <"; + s << '<' << QPdf::toHex((ushort)start, buf) << "> <"; s << QPdf::toHex((ushort)(endnonlinear - 1), buf) << "> "; if (endnonlinear == start + 1) { - s << "<" << QPdf::toHex((ushort)reverseMap[start], buf) << ">\n"; + s << '<' << QPdf::toHex((ushort)reverseMap[start], buf) << ">\n"; } else { - s << "["; + s << '['; for (int i = start; i < endnonlinear; ++i) { - s << "<" << QPdf::toHex((ushort)reverseMap[i], buf) << "> "; + s << '<' << QPdf::toHex((ushort)reverseMap[i], buf) << "> "; } s << "]\n"; } @@ -508,9 +508,9 @@ QByteArray QFontSubset::createToUnicodeMap() const int uc_end = uc_start + len - 1; if ((uc_end >> 8) != (uc_start >> 8)) len = 256 - (uc_start & 0xff); - s << "<" << QPdf::toHex((ushort)startLinear, buf) << "> <"; + s << '<' << QPdf::toHex((ushort)startLinear, buf) << "> <"; s << QPdf::toHex((ushort)(startLinear + len - 1), buf) << "> "; - s << "<" << QPdf::toHex((ushort)reverseMap[startLinear], buf) << ">\n"; + s << '<' << QPdf::toHex((ushort)reverseMap[startLinear], buf) << ">\n"; checkRanges(ts, ranges, nranges); startLinear += len; } @@ -1655,7 +1655,7 @@ QByteArray QFontSubset::toType1() const QByteArray id = QByteArray::number(object_id); QByteArray psname = properties.postscriptName; - psname.replace(" ", ""); + psname.replace(' ', ""); standard_font = false; @@ -1681,12 +1681,12 @@ QByteArray QFontSubset::toType1() const #endif s << "/F" << id << "-Base\n"; if (standard_font) { - s << "/" << psname << " findfont\n" + s << '/' << psname << " findfont\n" "0 dict copy dup /NumGlyphs 0 put dup /CMap 256 array put def\n"; } else { s << "<<\n"; if(!psname.isEmpty()) - s << "/FontName /" << psname << "\n"; + s << "/FontName /" << psname << '\n'; s << "/FontInfo <</FsType " << (int)fontEngine->fsType << ">>\n" "/FontType 1\n" "/PaintType 0\n" @@ -1722,7 +1722,7 @@ QByteArray QFontSubset::type1AddedGlyphs() const int nGlyphs = glyph_indices.size(); QByteArray id = QByteArray::number(object_id); - s << "F" << id << "-Base [\n"; + s << 'F' << id << "-Base [\n"; for (int i = downloaded_glyphs; i < nGlyphs; ++i) { glyph_t g = glyph_indices.at(i); QPainterPath path; diff --git a/src/gui/text/qfontsubset_p.h b/src/gui/text/qfontsubset_p.h index cd9fe51..62d2b1d 100644 --- a/src/gui/text/qfontsubset_p.h +++ b/src/gui/text/qfontsubset_p.h @@ -1,7 +1,6 @@ /**************************************************************************** ** ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** ** This file is part of the QtGui module of the Qt Toolkit. @@ -21,9 +20,10 @@ ** ensure the GNU Lesser General Public License version 2.1 requirements ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. ** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.1, included in the file LGPL_EXCEPTION.txt in this +** package. ** ** If you have questions regarding the use of this file, please contact ** Nokia at qt-info@nokia.com. diff --git a/src/gui/text/qfragmentmap.cpp b/src/gui/text/qfragmentmap.cpp index 0d2493c..52056dc 100644 --- a/src/gui/text/qfragmentmap.cpp +++ b/src/gui/text/qfragmentmap.cpp @@ -1,7 +1,6 @@ /**************************************************************************** ** ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** ** This file is part of the QtGui module of the Qt Toolkit. @@ -21,9 +20,10 @@ ** ensure the GNU Lesser General Public License version 2.1 requirements ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. ** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.1, included in the file LGPL_EXCEPTION.txt in this +** package. ** ** If you have questions regarding the use of this file, please contact ** Nokia at qt-info@nokia.com. diff --git a/src/gui/text/qfragmentmap_p.h b/src/gui/text/qfragmentmap_p.h index 473ad40..6d8c8fa 100644 --- a/src/gui/text/qfragmentmap_p.h +++ b/src/gui/text/qfragmentmap_p.h @@ -1,7 +1,6 @@ /**************************************************************************** ** ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** ** This file is part of the QtGui module of the Qt Toolkit. @@ -21,9 +20,10 @@ ** ensure the GNU Lesser General Public License version 2.1 requirements ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. ** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.1, included in the file LGPL_EXCEPTION.txt in this +** package. ** ** If you have questions regarding the use of this file, please contact ** Nokia at qt-info@nokia.com. @@ -214,6 +214,7 @@ private: template <class Fragment> QFragmentMapData<Fragment>::QFragmentMapData() + : fragments(0) { init(); } @@ -221,12 +222,19 @@ QFragmentMapData<Fragment>::QFragmentMapData() template <class Fragment> void QFragmentMapData<Fragment>::init() { - fragments = (Fragment *)malloc(64*fragmentSize); + // the following code will realloc an existing fragment or create a new one. + // it will also ignore errors when shrinking an existing fragment. + Fragment *newFragments = (Fragment *)realloc(fragments, 64*fragmentSize); + if (newFragments) { + fragments = newFragments; + head->allocated = 64; + } + Q_CHECK_PTR(fragments); + head->tag = (((quint32)'p') << 24) | (((quint32)'m') << 16) | (((quint32)'a') << 8) | 'p'; //TAG('p', 'm', 'a', 'p'); head->root = 0; head->freelist = 1; head->node_count = 0; - head->allocated = 64; // mark all items to the right as unused F(head->freelist).right = 0; } @@ -234,7 +242,7 @@ void QFragmentMapData<Fragment>::init() template <class Fragment> QFragmentMapData<Fragment>::~QFragmentMapData() { - free(head); + free(fragments); } template <class Fragment> @@ -247,7 +255,9 @@ uint QFragmentMapData<Fragment>::createFragment() // need to create some free space uint needed = qAllocMore((freePos+1)*fragmentSize, 0); Q_ASSERT(needed/fragmentSize > head->allocated); - fragments = (Fragment *)realloc(fragments, needed); + Fragment *newFragments = (Fragment *)realloc(fragments, needed); + Q_CHECK_PTR(newFragments); + fragments = newFragments; head->allocated = needed/fragmentSize; F(freePos).right = 0; } @@ -787,6 +797,8 @@ public: QFragmentMap() {} ~QFragmentMap() { + if (!data.fragments) + return; // in case of out-of-memory, we won't have fragments for (Iterator it = begin(); !it.atEnd(); ++it) it.value()->free(); } @@ -794,7 +806,6 @@ public: inline void clear() { for (Iterator it = begin(); !it.atEnd(); ++it) it.value()->free(); - ::free(data.head); data.init(); } diff --git a/src/gui/text/qpfutil.cpp b/src/gui/text/qpfutil.cpp index 4622819..ee4159b 100644 --- a/src/gui/text/qpfutil.cpp +++ b/src/gui/text/qpfutil.cpp @@ -1,7 +1,6 @@ /**************************************************************************** ** ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** ** This file is part of the QtGui module of the Qt Toolkit. @@ -21,9 +20,10 @@ ** ensure the GNU Lesser General Public License version 2.1 requirements ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. ** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.1, included in the file LGPL_EXCEPTION.txt in this +** package. ** ** If you have questions regarding the use of this file, please contact ** Nokia at qt-info@nokia.com. diff --git a/src/gui/text/qsyntaxhighlighter.cpp b/src/gui/text/qsyntaxhighlighter.cpp index 90226fd..7a53759 100644 --- a/src/gui/text/qsyntaxhighlighter.cpp +++ b/src/gui/text/qsyntaxhighlighter.cpp @@ -1,7 +1,6 @@ /**************************************************************************** ** ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** ** This file is part of the QtGui module of the Qt Toolkit. @@ -21,9 +20,10 @@ ** ensure the GNU Lesser General Public License version 2.1 requirements ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. ** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.1, included in the file LGPL_EXCEPTION.txt in this +** package. ** ** If you have questions regarding the use of this file, please contact ** Nokia at qt-info@nokia.com. @@ -65,6 +65,18 @@ public: void _q_reformatBlocks(int from, int charsRemoved, int charsAdded); void reformatBlock(QTextBlock block); + + inline void rehighlight(QTextCursor &cursor, QTextCursor::MoveOperation operation) { + QObject::disconnect(doc, SIGNAL(contentsChange(int,int,int)), + q_func(), SLOT(_q_reformatBlocks(int,int,int))); + cursor.beginEditBlock(); + int from = cursor.position(); + cursor.movePosition(operation); + _q_reformatBlocks(from, 0, cursor.position() - from); + cursor.endEditBlock(); + QObject::connect(doc, SIGNAL(contentsChange(int,int,int)), + q_func(), SLOT(_q_reformatBlocks(int,int,int))); + } inline void _q_delayedRehighlight() { if (!rehighlightPending) @@ -207,7 +219,7 @@ void QSyntaxHighlighterPrivate::reformatBlock(QTextBlock block) \since 4.1 - \ingroup text + \ingroup richtext-processing The QSyntaxHighlighter class is a base class for implementing QTextEdit syntax highlighters. A syntax highligher automatically @@ -355,7 +367,9 @@ QTextDocument *QSyntaxHighlighter::document() const /*! \since 4.2 - Redoes the highlighting of the whole document. + Reapplies the highlighting to the whole document. + + \sa rehighlightBlock() */ void QSyntaxHighlighter::rehighlight() { @@ -363,15 +377,25 @@ void QSyntaxHighlighter::rehighlight() if (!d->doc) return; - disconnect(d->doc, SIGNAL(contentsChange(int,int,int)), - this, SLOT(_q_reformatBlocks(int,int,int))); QTextCursor cursor(d->doc); - cursor.beginEditBlock(); - cursor.movePosition(QTextCursor::End); - d->_q_reformatBlocks(0, 0, cursor.position()); - cursor.endEditBlock(); - connect(d->doc, SIGNAL(contentsChange(int,int,int)), - this, SLOT(_q_reformatBlocks(int,int,int))); + d->rehighlight(cursor, QTextCursor::End); +} + +/*! + \since 4.6 + + Reapplies the highlighting to the given QTextBlock \a block. + + \sa rehighlight() +*/ +void QSyntaxHighlighter::rehighlightBlock(const QTextBlock &block) +{ + Q_D(QSyntaxHighlighter); + if (!d->doc) + return; + + QTextCursor cursor(block); + d->rehighlight(cursor, QTextCursor::EndOfBlock); } /*! diff --git a/src/gui/text/qsyntaxhighlighter.h b/src/gui/text/qsyntaxhighlighter.h index 54e404d..ecdddba 100644 --- a/src/gui/text/qsyntaxhighlighter.h +++ b/src/gui/text/qsyntaxhighlighter.h @@ -1,7 +1,6 @@ /**************************************************************************** ** ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** ** This file is part of the QtGui module of the Qt Toolkit. @@ -21,9 +20,10 @@ ** ensure the GNU Lesser General Public License version 2.1 requirements ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. ** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.1, included in the file LGPL_EXCEPTION.txt in this +** package. ** ** If you have questions regarding the use of this file, please contact ** Nokia at qt-info@nokia.com. @@ -78,6 +78,7 @@ public: public Q_SLOTS: void rehighlight(); + void rehighlightBlock(const QTextBlock &block); protected: virtual void highlightBlock(const QString &text) = 0; diff --git a/src/gui/text/qtextcontrol.cpp b/src/gui/text/qtextcontrol.cpp index 25d17a1..7ee0729 100644 --- a/src/gui/text/qtextcontrol.cpp +++ b/src/gui/text/qtextcontrol.cpp @@ -1,7 +1,6 @@ /**************************************************************************** ** ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** ** This file is part of the QtGui module of the Qt Toolkit. @@ -21,9 +20,10 @@ ** ensure the GNU Lesser General Public License version 2.1 requirements ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. ** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.1, included in the file LGPL_EXCEPTION.txt in this +** package. ** ** If you have questions regarding the use of this file, please contact ** Nokia at qt-info@nokia.com. @@ -82,7 +82,7 @@ #include "private/qapplication_p.h" #include "private/qshortcutmap_p.h" #include <qkeysequence.h> -#define ACCEL_KEY(k) (!qApp->d_func()->shortcutMap.hasShortcutForKeySequence(k) ? QLatin1String("\t") + QString(QKeySequence(k)) : QString()) +#define ACCEL_KEY(k) (!qApp->d_func()->shortcutMap.hasShortcutForKeySequence(k) ? QLatin1Char('\t') + QString(QKeySequence(k)) : QString()) #else #define ACCEL_KEY(k) QString() #endif @@ -394,7 +394,7 @@ void QTextControlPrivate::init(Qt::TextFormat format, const QString &text, QText Q_Q(QTextControl); setContent(format, text, document); - QWidget *parentWidget = qobject_cast<QWidget*>(q->parent()); + QWidget *parentWidget = qobject_cast<QWidget*>(parent); if (parentWidget) { QTextOption opt = doc->defaultTextOption(); opt.setTextDirection(parentWidget->layoutDirection()); @@ -1611,6 +1611,9 @@ void QTextControlPrivate::mouseMoveEvent(Qt::MouseButtons buttons, const QPointF if (cursor.position() != oldCursorPos) emit q->cursorPositionChanged(); _q_updateCurrentCharFormatAndSelection(); + if (QInputContext *ic = inputContext()) { + ic->update(); + } } else { //emit q->visibilityRequest(QRectF(mousePos, QSizeF(1, 1))); if (cursor.position() != oldCursorPos) @@ -1712,7 +1715,7 @@ void QTextControlPrivate::mouseDoubleClickEvent(QEvent *e, Qt::MouseButton butto selectedWordOnDoubleClick = cursor; trippleClickPoint = pos; - trippleClickTimer.start(qApp->doubleClickInterval(), q); + trippleClickTimer.start(QApplication::doubleClickInterval(), q); if (doEmit) { selectionChanged(); #ifndef QT_NO_CLIPBOARD @@ -1813,13 +1816,18 @@ bool QTextControlPrivate::dropEvent(const QMimeData *mimeData, const QPointF &po void QTextControlPrivate::inputMethodEvent(QInputMethodEvent *e) { + Q_Q(QTextControl); if (!(interactionFlags & Qt::TextEditable) || cursor.isNull()) { e->ignore(); return; } - cursor.beginEditBlock(); + bool isGettingInput = !e->commitString().isEmpty() || !e->preeditString().isEmpty() + || e->replacementLength() > 0; - cursor.removeSelectedText(); + if (isGettingInput) { + cursor.beginEditBlock(); + cursor.removeSelectedText(); + } // insert commit string if (!e->commitString().isEmpty() || e->replacementLength()) { @@ -1829,6 +1837,18 @@ void QTextControlPrivate::inputMethodEvent(QInputMethodEvent *e) c.insertText(e->commitString()); } + for (int i = 0; i < e->attributes().size(); ++i) { + const QInputMethodEvent::Attribute &a = e->attributes().at(i); + if (a.type == QInputMethodEvent::Selection) { + QTextCursor oldCursor = cursor; + int blockStart = a.start + cursor.block().position(); + cursor.setPosition(blockStart, QTextCursor::MoveAnchor); + cursor.setPosition(blockStart + a.length, QTextCursor::KeepAnchor); + q->ensureCursorVisible(); + repaintOldAndNewSelection(oldCursor); + } + } + QTextBlock block = cursor.block(); QTextLayout *layout = block.layout(); layout->setPreeditArea(cursor.position() - block.position(), e->preeditString()); @@ -1852,7 +1872,9 @@ void QTextControlPrivate::inputMethodEvent(QInputMethodEvent *e) } } layout->setAdditionalFormats(overrides); - cursor.endEditBlock(); + + if (isGettingInput) + cursor.endEditBlock(); } QVariant QTextControl::inputMethodQuery(Qt::InputMethodQuery property) const @@ -1865,11 +1887,15 @@ QVariant QTextControl::inputMethodQuery(Qt::InputMethodQuery property) const case Qt::ImFont: return QVariant(d->cursor.charFormat().font()); case Qt::ImCursorPosition: - return QVariant(d->cursor.selectionEnd() - block.position()); + return QVariant(d->cursor.position() - block.position()); case Qt::ImSurroundingText: return QVariant(block.text()); case Qt::ImCurrentSelection: return QVariant(d->cursor.selectedText()); + case Qt::ImMaximumTextLength: + return QVariant(); // No limit. + case Qt::ImAnchorPosition: + return QVariant(qBound(0, d->cursor.anchor() - block.position(), block.length())); default: return QVariant(); } @@ -2262,7 +2288,7 @@ void QTextControl::print(QPrinter *printer) const { #ifndef QT_NO_PRINTER Q_D(const QTextControl); - if (printer && !printer->isValid()) + if (!printer || !printer->isValid()) return; QTextDocument *tempDoc = 0; const QTextDocument *doc = d->doc; diff --git a/src/gui/text/qtextcontrol_p.h b/src/gui/text/qtextcontrol_p.h index 263af31..e36311d 100644 --- a/src/gui/text/qtextcontrol_p.h +++ b/src/gui/text/qtextcontrol_p.h @@ -1,7 +1,6 @@ /**************************************************************************** ** ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** ** This file is part of the QtGui module of the Qt Toolkit. @@ -21,9 +20,10 @@ ** ensure the GNU Lesser General Public License version 2.1 requirements ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. ** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.1, included in the file LGPL_EXCEPTION.txt in this +** package. ** ** If you have questions regarding the use of this file, please contact ** Nokia at qt-info@nokia.com. diff --git a/src/gui/text/qtextcontrol_p_p.h b/src/gui/text/qtextcontrol_p_p.h index ca9db9f..c892554 100644 --- a/src/gui/text/qtextcontrol_p_p.h +++ b/src/gui/text/qtextcontrol_p_p.h @@ -1,7 +1,6 @@ /**************************************************************************** ** ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** ** This file is part of the QtGui module of the Qt Toolkit. @@ -21,9 +20,10 @@ ** ensure the GNU Lesser General Public License version 2.1 requirements ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. ** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.1, included in the file LGPL_EXCEPTION.txt in this +** package. ** ** If you have questions regarding the use of this file, please contact ** Nokia at qt-info@nokia.com. diff --git a/src/gui/text/qtextcursor.cpp b/src/gui/text/qtextcursor.cpp index 9fd1f0d..9aebc64 100644 --- a/src/gui/text/qtextcursor.cpp +++ b/src/gui/text/qtextcursor.cpp @@ -1,7 +1,6 @@ /**************************************************************************** ** ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** ** This file is part of the QtGui module of the Qt Toolkit. @@ -21,9 +20,10 @@ ** ensure the GNU Lesser General Public License version 2.1 requirements ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. ** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.1, included in the file LGPL_EXCEPTION.txt in this +** package. ** ** If you have questions regarding the use of this file, please contact ** Nokia at qt-info@nokia.com. @@ -125,7 +125,7 @@ QTextCursorPrivate::AdjustResult QTextCursorPrivate::adjustPosition(int position void QTextCursorPrivate::setX() { - if (priv && priv->isInEditBlock()) { + if (priv->isInEditBlock()) { x = -1; // mark dirty return; } @@ -145,7 +145,6 @@ void QTextCursorPrivate::remove() { if (anchor == position) return; - priv->beginEditBlock(); currentCharFormat = -1; int pos1 = position; int pos2 = adjusted_anchor; @@ -159,15 +158,18 @@ void QTextCursorPrivate::remove() // deleting inside table? -> delete only content QTextTable *table = complexSelectionTable(); if (table) { + priv->beginEditBlock(); int startRow, startCol, numRows, numCols; selectedTableCells(&startRow, &numRows, &startCol, &numCols); clearCells(table, startRow, startCol, numRows, numCols, op); + adjusted_anchor = anchor = position; + priv->endEditBlock(); } else { priv->remove(pos1, pos2-pos1, op); + adjusted_anchor = anchor = position; + priv->finishEdit(); } - adjusted_anchor = anchor = position; - priv->endEditBlock(); } void QTextCursorPrivate::clearCells(QTextTable *table, int startRow, int startCol, int numRows, int numCols, QTextUndoCommand::Operation op) @@ -853,9 +855,9 @@ QTextLayout *QTextCursorPrivate::blockLayout(QTextBlock &block) const{ \brief The QTextCursor class offers an API to access and modify QTextDocuments. - \ingroup text + \ingroup richtext-processing \ingroup shared - \mainclass + Text cursors are objects that are used to access and modify the contents and underlying structure of text documents via a programming interface @@ -1291,9 +1293,14 @@ void QTextCursor::insertText(const QString &text, const QTextCharFormat &_format QTextCharFormat format = _format; format.clearProperty(QTextFormat::ObjectIndex); - d->priv->beginEditBlock(); + bool hasEditBlock = false; + + if (d->anchor != d->position) { + hasEditBlock = true; + d->priv->beginEditBlock(); + d->remove(); + } - d->remove(); if (!text.isEmpty()) { QTextFormatCollection *formats = d->priv->formatCollection(); int formatIdx = formats->indexForFormat(format); @@ -1323,6 +1330,11 @@ void QTextCursor::insertText(const QString &text, const QTextCharFormat &_format || ch == QChar::ParagraphSeparator || ch == QLatin1Char('\r')) { + if (!hasEditBlock) { + hasEditBlock = true; + d->priv->beginEditBlock(); + } + if (blockEnd > blockStart) d->priv->insert(d->position, textStart + blockStart, blockEnd - blockStart, formatIdx); @@ -1333,7 +1345,8 @@ void QTextCursor::insertText(const QString &text, const QTextCharFormat &_format if (textStart + blockStart < textEnd) d->priv->insert(d->position, textStart + blockStart, textEnd - textStart - blockStart, formatIdx); } - d->priv->endEditBlock(); + if (hasEditBlock) + d->priv->endEditBlock(); d->setX(); } @@ -1348,12 +1361,15 @@ void QTextCursor::deleteChar() if (!d || !d->priv) return; - if (d->position == d->anchor) { - if (!d->canDelete(d->position)) - return; - d->adjusted_anchor = d->anchor = - d->priv->nextCursorPosition(d->anchor, QTextLayout::SkipCharacters); + if (d->position != d->anchor) { + removeSelectedText(); + return; } + + if (!d->canDelete(d->position)) + return; + d->adjusted_anchor = d->anchor = + d->priv->nextCursorPosition(d->anchor, QTextLayout::SkipCharacters); d->remove(); d->setX(); } @@ -1368,27 +1384,29 @@ void QTextCursor::deletePreviousChar() { if (!d || !d->priv) return; - - if (d->position == d->anchor) { - if (d->anchor < 1 || !d->canDelete(d->anchor-1)) - return; - d->anchor--; - - QTextDocumentPrivate::FragmentIterator fragIt = d->priv->find(d->anchor); - const QTextFragmentData * const frag = fragIt.value(); - int fpos = fragIt.position(); - QChar uc = d->priv->buffer().at(d->anchor - fpos + frag->stringPosition); - if (d->anchor > fpos && uc.unicode() >= 0xdc00 && uc.unicode() < 0xe000) { - // second half of a surrogate, check if we have the first half as well, - // if yes delete both at once - uc = d->priv->buffer().at(d->anchor - 1 - fpos + frag->stringPosition); - if (uc.unicode() >= 0xd800 && uc.unicode() < 0xdc00) - --d->anchor; - } - - d->adjusted_anchor = d->anchor; + + if (d->position != d->anchor) { + removeSelectedText(); + return; } - + + if (d->anchor < 1 || !d->canDelete(d->anchor-1)) + return; + d->anchor--; + + QTextDocumentPrivate::FragmentIterator fragIt = d->priv->find(d->anchor); + const QTextFragmentData * const frag = fragIt.value(); + int fpos = fragIt.position(); + QChar uc = d->priv->buffer().at(d->anchor - fpos + frag->stringPosition); + if (d->anchor > fpos && uc.unicode() >= 0xdc00 && uc.unicode() < 0xe000) { + // second half of a surrogate, check if we have the first half as well, + // if yes delete both at once + uc = d->priv->buffer().at(d->anchor - 1 - fpos + frag->stringPosition); + if (uc.unicode() >= 0xd800 && uc.unicode() < 0xdc00) + --d->anchor; + } + + d->adjusted_anchor = d->anchor; d->remove(); d->setX(); } @@ -1504,7 +1522,9 @@ void QTextCursor::removeSelectedText() if (!d || !d->priv || d->position == d->anchor) return; + d->priv->beginEditBlock(); d->remove(); + d->priv->endEditBlock(); d->setX(); } @@ -1836,6 +1856,8 @@ bool QTextCursor::atStart() const } /*! + \since 4.6 + Returns true if the cursor is at the end of the document; otherwise returns false. diff --git a/src/gui/text/qtextcursor.h b/src/gui/text/qtextcursor.h index c75e028..3db2a21 100644 --- a/src/gui/text/qtextcursor.h +++ b/src/gui/text/qtextcursor.h @@ -1,7 +1,6 @@ /**************************************************************************** ** ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** ** This file is part of the QtGui module of the Qt Toolkit. @@ -21,9 +20,10 @@ ** ensure the GNU Lesser General Public License version 2.1 requirements ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. ** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.1, included in the file LGPL_EXCEPTION.txt in this +** package. ** ** If you have questions regarding the use of this file, please contact ** Nokia at qt-info@nokia.com. diff --git a/src/gui/text/qtextcursor_p.h b/src/gui/text/qtextcursor_p.h index 2649478..850ecaa 100644 --- a/src/gui/text/qtextcursor_p.h +++ b/src/gui/text/qtextcursor_p.h @@ -1,7 +1,6 @@ /**************************************************************************** ** ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** ** This file is part of the QtGui module of the Qt Toolkit. @@ -21,9 +20,10 @@ ** ensure the GNU Lesser General Public License version 2.1 requirements ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. ** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.1, included in the file LGPL_EXCEPTION.txt in this +** package. ** ** If you have questions regarding the use of this file, please contact ** Nokia at qt-info@nokia.com. diff --git a/src/gui/text/qtextdocument.cpp b/src/gui/text/qtextdocument.cpp index 0aaa38b..e565d0a 100644 --- a/src/gui/text/qtextdocument.cpp +++ b/src/gui/text/qtextdocument.cpp @@ -1,7 +1,6 @@ /**************************************************************************** ** ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** ** This file is part of the QtGui module of the Qt Toolkit. @@ -21,9 +20,10 @@ ** ensure the GNU Lesser General Public License version 2.1 requirements ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. ** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.1, included in the file LGPL_EXCEPTION.txt in this +** package. ** ** If you have questions regarding the use of this file, please contact ** Nokia at qt-info@nokia.com. @@ -247,8 +247,8 @@ QTextCodec *Qt::codecForHtml(const QByteArray &ba) \brief The QTextDocument class holds formatted text that can be viewed and edited using a QTextEdit. - \ingroup text - \mainclass + \ingroup richtext-processing + QTextDocument is a container for structured rich text documents, providing support for styled text and various types of document elements, such as @@ -2201,7 +2201,7 @@ void QTextHtmlExporter::emitTextLength(const char *attribute, const QTextLength if (length.type() == QTextLength::PercentageLength) html += QLatin1String("%\""); else - html += QLatin1String("\""); + html += QLatin1Char('\"'); } void QTextHtmlExporter::emitAlignment(Qt::Alignment align) @@ -2416,7 +2416,10 @@ void QTextHtmlExporter::emitFragment(const QTextFragment &fragment) static bool isOrderedList(int style) { return style == QTextListFormat::ListDecimal || style == QTextListFormat::ListLowerAlpha - || style == QTextListFormat::ListUpperAlpha; + || style == QTextListFormat::ListUpperAlpha + || style == QTextListFormat::ListUpperRoman + || style == QTextListFormat::ListLowerRoman + ; } void QTextHtmlExporter::emitBlockAttributes(const QTextBlock &block) @@ -2513,16 +2516,20 @@ void QTextHtmlExporter::emitBlock(const QTextBlock &block) case QTextListFormat::ListSquare: html += QLatin1String("<ul type=\"square\""); break; case QTextListFormat::ListLowerAlpha: html += QLatin1String("<ol type=\"a\""); break; case QTextListFormat::ListUpperAlpha: html += QLatin1String("<ol type=\"A\""); break; + case QTextListFormat::ListLowerRoman: html += QLatin1String("<ol type=\"i\""); break; + case QTextListFormat::ListUpperRoman: html += QLatin1String("<ol type=\"I\""); break; default: html += QLatin1String("<ul"); // ### should not happen } + html += QLatin1String(" style=\"margin-top: 0px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px;"); + if (format.hasProperty(QTextFormat::ListIndent)) { - html += QLatin1String(" style=\"-qt-list-indent: "); + html += QLatin1String(" -qt-list-indent: "); html += QString::number(format.indent()); - html += QLatin1String(";\""); + html += QLatin1Char(';'); } - html += QLatin1Char('>'); + html += QLatin1String("\">"); } html += QLatin1String("<li"); diff --git a/src/gui/text/qtextdocument.h b/src/gui/text/qtextdocument.h index e52716a..893be02 100644 --- a/src/gui/text/qtextdocument.h +++ b/src/gui/text/qtextdocument.h @@ -1,7 +1,6 @@ /**************************************************************************** ** ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** ** This file is part of the QtGui module of the Qt Toolkit. @@ -21,9 +20,10 @@ ** ensure the GNU Lesser General Public License version 2.1 requirements ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. ** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.1, included in the file LGPL_EXCEPTION.txt in this +** package. ** ** If you have questions regarding the use of this file, please contact ** Nokia at qt-info@nokia.com. diff --git a/src/gui/text/qtextdocument_p.cpp b/src/gui/text/qtextdocument_p.cpp index 1fdd166..4847235 100644 --- a/src/gui/text/qtextdocument_p.cpp +++ b/src/gui/text/qtextdocument_p.cpp @@ -1,7 +1,6 @@ /**************************************************************************** ** ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** ** This file is part of the QtGui module of the Qt Toolkit. @@ -21,9 +20,10 @@ ** ensure the GNU Lesser General Public License version 2.1 requirements ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. ** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.1, included in the file LGPL_EXCEPTION.txt in this +** package. ** ** If you have questions regarding the use of this file, please contact ** Nokia at qt-info@nokia.com. @@ -60,6 +60,15 @@ QT_BEGIN_NAMESPACE #define PMDEBUG if(0) qDebug +// The VxWorks DIAB compiler crashes when initializing the anonymouse union with { a7 } +#if !defined(Q_CC_DIAB) +# define QT_INIT_TEXTUNDOCOMMAND(c, a1, a2, a3, a4, a5, a6, a7, a8) \ + QTextUndoCommand c = { a1, a2, 0, 0, a3, a4, a5, a6, { a7 }, a8 } +#else +# define QT_INIT_TEXTUNDOCOMMAND(c, a1, a2, a3, a4, a5, a6, a7, a8) \ + QTextUndoCommand c = { a1, a2, 0, 0, a3, a4, a5, a6 }; c.blockFormat = a7; c.revision = a8 +#endif + /* Structure of a document: @@ -179,6 +188,7 @@ QTextDocumentPrivate::QTextDocumentPrivate() docChangeOldLength(0), docChangeLength(0), framesDirty(true), + rtFrame(0), initialBlockCharFormatIndex(-1) // set correctly later in init() { editBlock = 0; @@ -193,6 +203,8 @@ QTextDocumentPrivate::QTextDocumentPrivate() undoEnabled = true; inContentsChange = false; + inEdit = false; + defaultTextOption.setTabStop(80); // same as in qtextengine.cpp defaultTextOption.setWrapMode(QTextOption::WrapAtWordBoundaryOrAnywhere); @@ -207,7 +219,6 @@ QTextDocumentPrivate::QTextDocumentPrivate() void QTextDocumentPrivate::init() { - rtFrame = 0; framesDirty = false; bool undoState = undoEnabled; @@ -230,42 +241,48 @@ void QTextDocumentPrivate::clear() } QList<QTextCursorPrivate *>oldCursors = cursors; - cursors.clear(); - changedCursors.clear(); - - QMap<int, QTextObject *>::Iterator objectIt = objects.begin(); - while (objectIt != objects.end()) { - if (*objectIt != rtFrame) { - delete *objectIt; - objectIt = objects.erase(objectIt); - } else { - ++objectIt; + QT_TRY{ + cursors.clear(); + changedCursors.clear(); + + QMap<int, QTextObject *>::Iterator objectIt = objects.begin(); + while (objectIt != objects.end()) { + if (*objectIt != rtFrame) { + delete *objectIt; + objectIt = objects.erase(objectIt); + } else { + ++objectIt; + } } - } - // also clear out the remaining root frame pointer - // (we're going to delete the object further down) - objects.clear(); + // also clear out the remaining root frame pointer + // (we're going to delete the object further down) + objects.clear(); - title.clear(); - undoState = 0; - truncateUndoStack(); - text = QString(); - unreachableCharacterCount = 0; - modifiedState = 0; - modified = false; - formats = QTextFormatCollection(); - int len = fragments.length(); - fragments.clear(); - blocks.clear(); - cachedResources.clear(); - delete rtFrame; - init(); - cursors = oldCursors; - inContentsChange = true; - q->contentsChange(0, len, 0); - inContentsChange = false; - if (lout) - lout->documentChanged(0, len, 0); + title.clear(); + undoState = 0; + truncateUndoStack(); + text = QString(); + unreachableCharacterCount = 0; + modifiedState = 0; + modified = false; + formats = QTextFormatCollection(); + int len = fragments.length(); + fragments.clear(); + blocks.clear(); + cachedResources.clear(); + delete rtFrame; + rtFrame = 0; + init(); + cursors = oldCursors; + inContentsChange = true; + q->contentsChange(0, len, 0); + inContentsChange = false; + if (lout) + lout->documentChanged(0, len, 0); + } QT_CATCH(...) { + cursors = oldCursors; // at least recover the cursors + QT_RETHROW; + } } QTextDocumentPrivate::~QTextDocumentPrivate() @@ -404,9 +421,9 @@ int QTextDocumentPrivate::insertBlock(const QChar &blockSeparator, int b = blocks.findNode(pos); QTextBlockData *B = blocks.fragment(b); - QTextUndoCommand c = { QTextUndoCommand::BlockInserted, true, - op, charFormat, strPos, pos, { blockFormat }, - B->revision }; + QT_INIT_TEXTUNDOCOMMAND(c, QTextUndoCommand::BlockInserted, (editBlock != 0), + op, charFormat, strPos, pos, blockFormat, + B->revision); appendUndoItem(c); Q_ASSERT(undoState == undoStack.size()); @@ -439,20 +456,20 @@ void QTextDocumentPrivate::insert(int pos, int strPos, int strLength, int format Q_ASSERT(pos >= 0 && pos < fragments.length()); Q_ASSERT(formats.format(format).isCharFormat()); - beginEditBlock(); + beginEdit(); insert_string(pos, strPos, strLength, format, QTextUndoCommand::MoveCursor); if (undoEnabled) { int b = blocks.findNode(pos); QTextBlockData *B = blocks.fragment(b); - QTextUndoCommand c = { QTextUndoCommand::Inserted, true, - QTextUndoCommand::MoveCursor, format, strPos, pos, { strLength }, - B->revision }; + QT_INIT_TEXTUNDOCOMMAND(c, QTextUndoCommand::Inserted, (editBlock != 0), + QTextUndoCommand::MoveCursor, format, strPos, pos, strLength, + B->revision); appendUndoItem(c); B->revision = undoState; Q_ASSERT(undoState == undoStack.size()); } - endEditBlock(); + finishEdit(); } void QTextDocumentPrivate::insert(int pos, const QString &str, int format) @@ -565,6 +582,7 @@ void QTextDocumentPrivate::move(int pos, int to, int length, QTextUndoCommand::O if (pos == to) return; + beginEdit(); const bool needsInsert = to != -1; #if !defined(QT_NO_DEBUG) @@ -584,8 +602,6 @@ void QTextDocumentPrivate::move(int pos, int to, int length, QTextUndoCommand::O Q_ASSERT(startAndEndInSameFrame || endIsEndOfChildFrame || startIsStartOfFrameAndEndIsEndOfFrameWithCommonParent || isFirstTableCell); #endif - beginEditBlock(); - split(pos); split(pos+length); @@ -605,12 +621,12 @@ void QTextDocumentPrivate::move(int pos, int to, int length, QTextUndoCommand::O int blockRevision = B->revision; QTextFragmentData *X = fragments.fragment(x); - QTextUndoCommand c = { QTextUndoCommand::Removed, true, - op, X->format, X->stringPosition, key, { X->size_array[0] }, - blockRevision }; - QTextUndoCommand cInsert = { QTextUndoCommand::Inserted, true, - op, X->format, X->stringPosition, dstKey, { X->size_array[0] }, - blockRevision }; + QT_INIT_TEXTUNDOCOMMAND(c, QTextUndoCommand::Removed, (editBlock != 0), + op, X->format, X->stringPosition, key, X->size_array[0], + blockRevision); + QT_INIT_TEXTUNDOCOMMAND(cInsert, QTextUndoCommand::Inserted, (editBlock != 0), + op, X->format, X->stringPosition, dstKey, X->size_array[0], + blockRevision); if (key+1 != blocks.position(b)) { // qDebug("remove_string from %d length %d", key, X->size_array[0]); @@ -648,7 +664,7 @@ void QTextDocumentPrivate::move(int pos, int to, int length, QTextUndoCommand::O Q_ASSERT(blocks.length() == fragments.length()); - endEditBlock(); + finishEdit(); } void QTextDocumentPrivate::remove(int pos, int length, QTextUndoCommand::Operation op) @@ -722,8 +738,8 @@ void QTextDocumentPrivate::setCharFormat(int pos, int length, const QTextCharFor fragment->format = newFormatIdx; } - QTextUndoCommand c = { QTextUndoCommand::CharFormatChanged, true, QTextUndoCommand::MoveCursor, oldFormat, - 0, pos, { length }, 0 }; + QT_INIT_TEXTUNDOCOMMAND(c, QTextUndoCommand::CharFormatChanged, true, QTextUndoCommand::MoveCursor, oldFormat, + 0, pos, length, 0); appendUndoItem(c); pos += length; @@ -782,8 +798,8 @@ void QTextDocumentPrivate::setBlockFormat(const QTextBlock &from, const QTextBlo block(it)->invalidate(); - QTextUndoCommand c = { QTextUndoCommand::BlockFormatChanged, true, QTextUndoCommand::MoveCursor, oldFormat, - 0, it.position(), { 1 }, 0 }; + QT_INIT_TEXTUNDOCOMMAND(c, QTextUndoCommand::BlockFormatChanged, true, QTextUndoCommand::MoveCursor, oldFormat, + 0, it.position(), 1, 0); appendUndoItem(c); if (group != oldGroup) { @@ -951,14 +967,18 @@ int QTextDocumentPrivate::undoRedo(bool undo) B->revision = c.revision; } - if (undo) { - if (undoState == 0 || !undoStack[undoState-1].block) - break; - } else { + if (!undo) ++undoState; - if (undoState == undoStack.size() || !undoStack[undoState-1].block) - break; - } + + bool inBlock = ( + undoState > 0 + && undoState < undoStack.size() + && undoStack[undoState].block_part + && undoStack[undoState-1].block_part + && !undoStack[undoState-1].block_end + ); + if (!inBlock) + break; } undoEnabled = true; int editPos = -1; @@ -983,7 +1003,8 @@ void QTextDocumentPrivate::appendUndoItem(QAbstractUndoItem *item) QTextUndoCommand c; c.command = QTextUndoCommand::Custom; - c.block = editBlock != 0; + c.block_part = editBlock != 0; + c.block_end = 0; c.operation = QTextUndoCommand::MoveCursor; c.format = 0; c.strPos = 0; @@ -1004,8 +1025,13 @@ void QTextDocumentPrivate::appendUndoItem(const QTextUndoCommand &c) if (!undoStack.isEmpty() && modified) { QTextUndoCommand &last = undoStack[undoState - 1]; - if (last.tryMerge(c)) - return; + + if ( (last.block_part && c.block_part && !last.block_end) // part of the same block => can merge + || (!c.block_part && !last.block_part)) { // two single undo items => can merge + + if (last.tryMerge(c)) + return; + } } if (modifiedState > undoState) modifiedState = -1; @@ -1013,6 +1039,9 @@ void QTextDocumentPrivate::appendUndoItem(const QTextUndoCommand &c) undoState++; emitUndoAvailable(true); emitRedoAvailable(false); + + if (!c.block_part) + emit document()->undoCommandAdded(); } void QTextDocumentPrivate::truncateUndoStack() @@ -1077,22 +1106,33 @@ void QTextDocumentPrivate::joinPreviousEditBlock() beginEditBlock(); if (undoEnabled && undoState) - undoStack[undoState - 1].block = true; + undoStack[undoState - 1].block_end = false; } void QTextDocumentPrivate::endEditBlock() { - Q_Q(QTextDocument); if (--editBlock) return; if (undoEnabled && undoState > 0) { - const bool wasBlocking = undoStack[undoState - 1].block; - undoStack[undoState - 1].block = false; - if (wasBlocking) + if (undoStack[undoState - 1].block_part) { + undoStack[undoState - 1].block_end = true; emit document()->undoCommandAdded(); + } } + finishEdit(); +} + +void QTextDocumentPrivate::finishEdit() +{ + Q_Q(QTextDocument); + + if (editBlock) + return; + + inEdit = false; + if (framesDirty) scan_frames(docChangeFrom, docChangeOldLength, docChangeLength); @@ -1162,7 +1202,7 @@ void QTextDocumentPrivate::adjustDocumentChangesAndCursors(int from, int addedOr for (int i = 0; i < cursors.size(); ++i) { QTextCursorPrivate *curs = cursors.at(i); if (curs->adjustPosition(from, addedOrRemoved, op) == QTextCursorPrivate::CursorMoved) { - if (editBlock) { + if (editBlock || inEdit) { if (!changedCursors.contains(curs)) changedCursors.append(curs); } else { @@ -1279,8 +1319,8 @@ void QTextDocumentPrivate::changeObjectFormat(QTextObject *obj, int format) if (f) documentChange(f->firstPosition(), f->lastPosition() - f->firstPosition()); - QTextUndoCommand c = { QTextUndoCommand::GroupFormatChange, true, QTextUndoCommand::MoveCursor, oldFormatIndex, - 0, 0, { obj->d_func()->objectIndex }, 0 }; + QT_INIT_TEXTUNDOCOMMAND(c, QTextUndoCommand::GroupFormatChange, (editBlock != 0), QTextUndoCommand::MoveCursor, oldFormatIndex, + 0, 0, obj->d_func()->objectIndex, 0); appendUndoItem(c); endEditBlock(); diff --git a/src/gui/text/qtextdocument_p.h b/src/gui/text/qtextdocument_p.h index bcce675..3c207ff 100644 --- a/src/gui/text/qtextdocument_p.h +++ b/src/gui/text/qtextdocument_p.h @@ -1,7 +1,6 @@ /**************************************************************************** ** ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** ** This file is part of the QtGui module of the Qt Toolkit. @@ -21,9 +20,10 @@ ** ensure the GNU Lesser General Public License version 2.1 requirements ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. ** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.1, included in the file LGPL_EXCEPTION.txt in this +** package. ** ** If you have questions regarding the use of this file, please contact ** Nokia at qt-info@nokia.com. @@ -139,7 +139,9 @@ public: MoveCursor = 1 }; quint16 command; - quint8 block; ///< All undo commands that have this set to zero/false are combined with the preceding command on undo/redo. + uint block_part : 1; // all commands that are part of an undo block (including the first and the last one) have this set to 1 + uint block_end : 1; // the last command in an undo block has this set to 1. + uint block_padding : 6; // padding since block used to be a quint8 quint8 operation; int format; quint32 strPos; @@ -202,6 +204,8 @@ public: inline void beginEditBlock() { editBlock++; } void joinPreviousEditBlock(); void endEditBlock(); + inline void beginEdit() { inEdit = true; } + void finishEdit(); inline bool isInEditBlock() const { return editBlock; } void enableUndoRedo(bool enable); inline bool isUndoRedoEnabled() const { return undoEnabled; } @@ -334,8 +338,9 @@ public: QCss::StyleSheet parsedDefaultStyleSheet; #endif int maximumBlockCount; - bool needsEnsureMaximumBlockCount; - bool inContentsChange; + uint needsEnsureMaximumBlockCount : 1; + uint inContentsChange : 1; + uint inEdit : 1; // between beginEdit() and finishEdit() QSizeF pageSize; QString title; QString url; diff --git a/src/gui/text/qtextdocumentfragment.cpp b/src/gui/text/qtextdocumentfragment.cpp index bf1fdf6..6f89b27 100644 --- a/src/gui/text/qtextdocumentfragment.cpp +++ b/src/gui/text/qtextdocumentfragment.cpp @@ -1,7 +1,6 @@ /**************************************************************************** ** ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** ** This file is part of the QtGui module of the Qt Toolkit. @@ -21,9 +20,10 @@ ** ensure the GNU Lesser General Public License version 2.1 requirements ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. ** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.1, included in the file LGPL_EXCEPTION.txt in this +** package. ** ** If you have questions regarding the use of this file, please contact ** Nokia at qt-info@nokia.com. @@ -54,7 +54,11 @@ QT_BEGIN_NAMESPACE QTextCopyHelper::QTextCopyHelper(const QTextCursor &_source, const QTextCursor &_destination, bool forceCharFormat, const QTextCharFormat &fmt) +#if defined(Q_CC_DIAB) // compiler bug + : formatCollection(*_destination.d->priv->formatCollection()), originalText((const QString)_source.d->priv->buffer()) +#else : formatCollection(*_destination.d->priv->formatCollection()), originalText(_source.d->priv->buffer()) +#endif { src = _source.d->priv; dst = _destination.d->priv; @@ -255,7 +259,7 @@ void QTextDocumentFragmentPrivate::insert(QTextCursor &_cursor) const \brief The QTextDocumentFragment class represents a piece of formatted text from a QTextDocument. - \ingroup text + \ingroup richtext-processing \ingroup shared A QTextDocumentFragment is a fragment of rich text, that can be inserted into diff --git a/src/gui/text/qtextdocumentfragment.h b/src/gui/text/qtextdocumentfragment.h index 51ed1d2..499ad50 100644 --- a/src/gui/text/qtextdocumentfragment.h +++ b/src/gui/text/qtextdocumentfragment.h @@ -1,7 +1,6 @@ /**************************************************************************** ** ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** ** This file is part of the QtGui module of the Qt Toolkit. @@ -21,9 +20,10 @@ ** ensure the GNU Lesser General Public License version 2.1 requirements ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. ** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.1, included in the file LGPL_EXCEPTION.txt in this +** package. ** ** If you have questions regarding the use of this file, please contact ** Nokia at qt-info@nokia.com. diff --git a/src/gui/text/qtextdocumentfragment_p.h b/src/gui/text/qtextdocumentfragment_p.h index a866578..e8c5091 100644 --- a/src/gui/text/qtextdocumentfragment_p.h +++ b/src/gui/text/qtextdocumentfragment_p.h @@ -1,7 +1,6 @@ /**************************************************************************** ** ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** ** This file is part of the QtGui module of the Qt Toolkit. @@ -21,9 +20,10 @@ ** ensure the GNU Lesser General Public License version 2.1 requirements ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. ** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.1, included in the file LGPL_EXCEPTION.txt in this +** package. ** ** If you have questions regarding the use of this file, please contact ** Nokia at qt-info@nokia.com. diff --git a/src/gui/text/qtextdocumentlayout.cpp b/src/gui/text/qtextdocumentlayout.cpp index 0f2347a..1e11f80 100644 --- a/src/gui/text/qtextdocumentlayout.cpp +++ b/src/gui/text/qtextdocumentlayout.cpp @@ -1,7 +1,6 @@ /**************************************************************************** ** ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** ** This file is part of the QtGui module of the Qt Toolkit. @@ -21,9 +20,10 @@ ** ensure the GNU Lesser General Public License version 2.1 requirements ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. ** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.1, included in the file LGPL_EXCEPTION.txt in this +** package. ** ** If you have questions regarding the use of this file, please contact ** Nokia at qt-info@nokia.com. @@ -198,8 +198,8 @@ public: if (v.isNull()) { return cellPadding; } else { - Q_ASSERT(v.type() == QVariant::Double); - return QFixed::fromReal(v.toDouble() * deviceScale); + Q_ASSERT(v.userType() == QVariant::Double || v.userType() == QMetaType::Float); + return QFixed::fromReal(v.toReal() * deviceScale); } } @@ -1383,6 +1383,8 @@ void QTextDocumentLayoutPrivate::drawListItem(const QPointF &offset, QPainter *p case QTextListFormat::ListDecimal: case QTextListFormat::ListLowerAlpha: case QTextListFormat::ListUpperAlpha: + case QTextListFormat::ListLowerRoman: + case QTextListFormat::ListUpperRoman: itemText = static_cast<QTextList *>(object)->itemText(bl); size.setWidth(fontMetrics.width(itemText)); size.setHeight(fontMetrics.height()); @@ -1426,7 +1428,9 @@ void QTextDocumentLayoutPrivate::drawListItem(const QPointF &offset, QPainter *p switch (style) { case QTextListFormat::ListDecimal: case QTextListFormat::ListLowerAlpha: - case QTextListFormat::ListUpperAlpha: { + case QTextListFormat::ListUpperAlpha: + case QTextListFormat::ListLowerRoman: + case QTextListFormat::ListUpperRoman: { QTextLayout layout(itemText, font, q->paintDevice()); layout.setCacheEnabled(true); QTextOption option(Qt::AlignLeft | Qt::AlignAbsolute); @@ -1990,9 +1994,12 @@ void QTextDocumentLayoutPrivate::positionFloat(QTextFrame *frame, QTextLine *cur } } - if (y + layoutStruct->frameY + fd->size.height > layoutStruct->pageBottom) { + bool frameSpansIntoNextPage = (y + layoutStruct->frameY + fd->size.height > layoutStruct->pageBottom); + if (frameSpansIntoNextPage && fd->size.height <= layoutStruct->pageHeight) { layoutStruct->newPage(); y = layoutStruct->y; + + frameSpansIntoNextPage = false; } y = findY(y, layoutStruct, fd->size.width); @@ -2013,6 +2020,11 @@ void QTextDocumentLayoutPrivate::positionFloat(QTextFrame *frame, QTextLine *cur // qDebug()<< "float positioned at " << fd->position.x << fd->position.y; fd->layoutDirty = false; + + // If the frame is a table, then positioning it will affect the size if it covers more than + // one page, because of page breaks and repeating the header. + if (qobject_cast<QTextTable *>(frame) != 0) + fd->sizeDirty = frameSpansIntoNextPage; } QRectF QTextDocumentLayoutPrivate::layoutFrame(QTextFrame *f, int layoutFrom, int layoutTo, QFixed parentY) @@ -2345,6 +2357,10 @@ void QTextDocumentLayoutPrivate::layoutFlow(QTextFrame::Iterator it, QLayoutStru positionFloat(c); + // If the size was made dirty when the position was set, layout again + if (cd->sizeDirty) + updateRect = layoutFrame(c, layoutFrom, layoutTo); + QRectF frameRect(cd->position.toPointF(), cd->size.toSizeF()); if (frameRect == oldFrameRect && updateRect.isValid()) @@ -2500,7 +2516,7 @@ void QTextDocumentLayoutPrivate::layoutBlock(const QTextBlock &bl, int blockPosi LDEBUG << "layoutBlock from=" << layoutFrom << "to=" << layoutTo; -// qDebug() << "layoutBlock; width" << layoutStruct->x_right - layoutStruct->x_left << "(maxWidth is btw" << tl->maximumWidth() << ")"; +// qDebug() << "layoutBlock; width" << layoutStruct->x_right - layoutStruct->x_left << "(maxWidth is btw" << tl->maximumWidth() << ')'; if (previousBlockFormat) { qreal margin = qMax(blockFormat.topMargin(), previousBlockFormat->bottomMargin()); @@ -2597,13 +2613,13 @@ void QTextDocumentLayoutPrivate::layoutBlock(const QTextBlock &bl, int blockPosi // float has been added in the meantime, redo layoutStruct->pendingFloats.clear(); - if (haveWordOrAnyWrapMode) { - option.setWrapMode(QTextOption::WrapAnywhere); - tl->setTextOption(option); - } - line.setLineWidth((right-left).toReal()); if (QFixed::fromReal(line.naturalTextWidth()) > right-left) { + if (haveWordOrAnyWrapMode) { + option.setWrapMode(QTextOption::WrapAnywhere); + tl->setTextOption(option); + } + layoutStruct->pendingFloats.clear(); // lines min width more than what we have layoutStruct->y = findY(layoutStruct->y, layoutStruct, QFixed::fromReal(line.naturalTextWidth())); @@ -2615,12 +2631,13 @@ void QTextDocumentLayoutPrivate::layoutBlock(const QTextBlock &bl, int blockPosi else right -= text_indent; line.setLineWidth(qMax<qreal>(line.naturalTextWidth(), (right-left).toReal())); - } - if (haveWordOrAnyWrapMode) { - option.setWrapMode(QTextOption::WordWrap); - tl->setTextOption(option); + if (haveWordOrAnyWrapMode) { + option.setWrapMode(QTextOption::WordWrap); + tl->setTextOption(option); + } } + } QFixed lineHeight = QFixed::fromReal(line.height()); @@ -3205,18 +3222,16 @@ bool QTextDocumentLayout::contentHasAlignment() const qreal QTextDocumentLayoutPrivate::scaleToDevice(qreal value) const { - QPaintDevice *dev = q_func()->paintDevice(); - if (!dev) + if (!paintDevice) return value; - return value * dev->logicalDpiY() / qreal(qt_defaultDpi()); + return value * paintDevice->logicalDpiY() / qreal(qt_defaultDpi()); } QFixed QTextDocumentLayoutPrivate::scaleToDevice(QFixed value) const { - QPaintDevice *dev = q_func()->paintDevice(); - if (!dev) + if (!paintDevice) return value; - return value * QFixed(dev->logicalDpiY()) / QFixed(qt_defaultDpi()); + return value * QFixed(paintDevice->logicalDpiY()) / QFixed(qt_defaultDpi()); } QT_END_NAMESPACE diff --git a/src/gui/text/qtextdocumentlayout_p.h b/src/gui/text/qtextdocumentlayout_p.h index eaa91ae..c2afc3a 100644 --- a/src/gui/text/qtextdocumentlayout_p.h +++ b/src/gui/text/qtextdocumentlayout_p.h @@ -1,7 +1,6 @@ /**************************************************************************** ** ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** ** This file is part of the QtGui module of the Qt Toolkit. @@ -21,9 +20,10 @@ ** ensure the GNU Lesser General Public License version 2.1 requirements ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. ** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.1, included in the file LGPL_EXCEPTION.txt in this +** package. ** ** If you have questions regarding the use of this file, please contact ** Nokia at qt-info@nokia.com. diff --git a/src/gui/text/qtextdocumentwriter.cpp b/src/gui/text/qtextdocumentwriter.cpp index 3c65c36..e5fe6a7 100644 --- a/src/gui/text/qtextdocumentwriter.cpp +++ b/src/gui/text/qtextdocumentwriter.cpp @@ -1,7 +1,6 @@ /**************************************************************************** ** ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** ** This file is part of the QtGui module of the Qt Toolkit. @@ -21,9 +20,10 @@ ** ensure the GNU Lesser General Public License version 2.1 requirements ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. ** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.1, included in the file LGPL_EXCEPTION.txt in this +** package. ** ** If you have questions regarding the use of this file, please contact ** Nokia at qt-info@nokia.com. @@ -76,7 +76,7 @@ public: \brief The QTextDocumentWriter class provides a format-independent interface for writing a QTextDocument to files or other devices. - \ingroup text + \ingroup richtext-processing \ingroup io To write a document, construct a QTextDocumentWriter object with either a diff --git a/src/gui/text/qtextdocumentwriter.h b/src/gui/text/qtextdocumentwriter.h index 7c502a7..d50c7af 100644 --- a/src/gui/text/qtextdocumentwriter.h +++ b/src/gui/text/qtextdocumentwriter.h @@ -1,7 +1,6 @@ /**************************************************************************** ** ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** ** This file is part of the QtGui module of the Qt Toolkit. @@ -21,9 +20,10 @@ ** ensure the GNU Lesser General Public License version 2.1 requirements ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. ** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.1, included in the file LGPL_EXCEPTION.txt in this +** package. ** ** If you have questions regarding the use of this file, please contact ** Nokia at qt-info@nokia.com. diff --git a/src/gui/text/qtextengine.cpp b/src/gui/text/qtextengine.cpp index d41567c..ba9145e 100644 --- a/src/gui/text/qtextengine.cpp +++ b/src/gui/text/qtextengine.cpp @@ -1,7 +1,6 @@ /**************************************************************************** ** ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** ** This file is part of the QtGui module of the Qt Toolkit. @@ -21,9 +20,10 @@ ** ensure the GNU Lesser General Public License version 2.1 requirements ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. ** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.1, included in the file LGPL_EXCEPTION.txt in this +** package. ** ** If you have questions regarding the use of this file, please contact ** Nokia at qt-info@nokia.com. @@ -363,7 +363,7 @@ static bool bidiItemize(QTextEngine *engine, QScriptAnalysis *analysis, QBidiCon #if (BIDI_DEBUG >= 2) // qDebug() << "pos=" << current << " dir=" << directions[dir] // << " current=" << directions[dirCurrent] << " last=" << directions[status.last] -// << " eor=" << eor << "/" << directions[status.eor] +// << " eor=" << eor << '/' << directions[status.eor] // << " sor=" << sor << " lastStrong=" // << directions[status.lastStrong] // << " level=" << (int)control.level << " override=" << (bool)control.override; @@ -868,7 +868,7 @@ void QTextEngine::shapeText(int item) const #if defined(Q_WS_MAC) shapeTextMac(item); -#elif defined(Q_OS_WINCE) +#elif defined(Q_WS_WINCE) shapeTextWithCE(item); #else shapeTextWithHarfbuzz(item); @@ -923,7 +923,7 @@ void QTextEngine::shapeText(int item) const si.width += glyphs.advances_x[i]; } -#if defined(Q_OS_WINCE) //TODO +#if defined(Q_WS_WINCE) //TODO // set the glyph attributes heuristically. Assumes a 1 to 1 relationship between chars and glyphs // and no reordering. // also computes logClusters heuristically @@ -2069,10 +2069,12 @@ void QTextEngine::LayoutData::reallocate(int totalGlyphs) int newAllocated = space_charAttributes + space_glyphs + space_logClusters; Q_ASSERT(newAllocated >= allocated); - void **old_mem = memory; - memory = (void **)::realloc(memory_on_stack ? 0 : old_mem, newAllocated*sizeof(void *)); - if (memory_on_stack && memory) - memcpy(memory, old_mem, allocated*sizeof(void *)); + void **newMem = memory; + newMem = (void **)::realloc(memory_on_stack ? 0 : memory, newAllocated*sizeof(void *)); + Q_CHECK_PTR(newMem); + if (memory_on_stack && newMem) + memcpy(newMem, memory, allocated*sizeof(void *)); + memory = newMem; memory_on_stack = false; void **m = memory; @@ -2243,6 +2245,28 @@ void QTextEngine::indexAdditionalFormats() } } +/* These two helper functions are used to determine whether we need to insert a ZWJ character + between the text that gets truncated and the ellipsis. This is important to get + correctly shaped results for arabic text. +*/ +static bool nextCharJoins(const QString &string, int pos) +{ + while (pos < string.length() && string.at(pos).category() == QChar::Mark_NonSpacing) + ++pos; + if (pos == string.length()) + return false; + return string.at(pos).joining() != QChar::OtherJoining; +} + +static bool prevCharJoins(const QString &string, int pos) +{ + while (pos > 0 && string.at(pos - 1).category() == QChar::Mark_NonSpacing) + --pos; + if (pos == 0) + return false; + return (string.at(pos - 1).joining() == QChar::Dual || string.at(pos - 1).joining() == QChar::Center); +} + QString QTextEngine::elidedText(Qt::TextElideMode mode, const QFixed &width, int flags) const { // qDebug() << "elidedText; available width" << width.toReal() << "text width:" << this->width(0, layoutData->string.length()).toReal(); @@ -2343,6 +2367,9 @@ QString QTextEngine::elidedText(Qt::TextElideMode mode, const QFixed &width, int } while (nextBreak < layoutData->string.length() && currentWidth < availableWidth); + if (nextCharJoins(layoutData->string, pos)) + ellipsisText.prepend(QChar(0x200d) /* ZWJ */); + return layoutData->string.left(pos) + ellipsisText; } else if (mode == Qt::ElideLeft) { QFixed currentWidth; @@ -2360,6 +2387,9 @@ QString QTextEngine::elidedText(Qt::TextElideMode mode, const QFixed &width, int } while (nextBreak > 0 && currentWidth < availableWidth); + if (prevCharJoins(layoutData->string, pos)) + ellipsisText.append(QChar(0x200d) /* ZWJ */); + return ellipsisText + layoutData->string.mid(pos); } else if (mode == Qt::ElideMiddle) { QFixed leftWidth; @@ -2389,6 +2419,11 @@ QString QTextEngine::elidedText(Qt::TextElideMode mode, const QFixed &width, int && nextRightBreak > 0 && leftWidth + rightWidth < availableWidth); + if (nextCharJoins(layoutData->string, leftPos)) + ellipsisText.prepend(QChar(0x200d) /* ZWJ */); + if (prevCharJoins(layoutData->string, rightPos)) + ellipsisText.append(QChar(0x200d) /* ZWJ */); + return layoutData->string.left(leftPos) + ellipsisText + layoutData->string.mid(rightPos); } diff --git a/src/gui/text/qtextengine_mac.cpp b/src/gui/text/qtextengine_mac.cpp index 4f20094..9957c84 100644 --- a/src/gui/text/qtextengine_mac.cpp +++ b/src/gui/text/qtextengine_mac.cpp @@ -1,7 +1,6 @@ /**************************************************************************** ** ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** ** This file is part of the QtGui module of the Qt Toolkit. @@ -21,9 +20,10 @@ ** ensure the GNU Lesser General Public License version 2.1 requirements ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. ** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.1, included in the file LGPL_EXCEPTION.txt in this +** package. ** ** If you have questions regarding the use of this file, please contact ** Nokia at qt-info@nokia.com. diff --git a/src/gui/text/qtextengine_p.h b/src/gui/text/qtextengine_p.h index 2e9066e..905bb71 100644 --- a/src/gui/text/qtextengine_p.h +++ b/src/gui/text/qtextengine_p.h @@ -1,7 +1,6 @@ /**************************************************************************** ** ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** ** This file is part of the QtGui module of the Qt Toolkit. @@ -21,9 +20,10 @@ ** ensure the GNU Lesser General Public License version 2.1 requirements ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. ** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.1, included in the file LGPL_EXCEPTION.txt in this +** package. ** ** If you have questions regarding the use of this file, please contact ** Nokia at qt-info@nokia.com. @@ -581,7 +581,7 @@ private: void addRequiredBoundaries() const; void shapeText(int item) const; void shapeTextWithHarfbuzz(int item) const; -#if defined(Q_OS_WINCE) +#if defined(Q_WS_WINCE) void shapeTextWithCE(int item) const; #endif #if defined(Q_WS_MAC) diff --git a/src/gui/text/qtextformat.cpp b/src/gui/text/qtextformat.cpp index 0450688..7a0d6ae 100644 --- a/src/gui/text/qtextformat.cpp +++ b/src/gui/text/qtextformat.cpp @@ -1,7 +1,6 @@ /**************************************************************************** ** ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** ** This file is part of the QtGui module of the Qt Toolkit. @@ -21,9 +20,10 @@ ** ensure the GNU Lesser General Public License version 2.1 requirements ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. ** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.1, included in the file LGPL_EXCEPTION.txt in this +** package. ** ** If you have questions regarding the use of this file, please contact ** Nokia at qt-info@nokia.com. @@ -57,7 +57,7 @@ QT_BEGIN_NAMESPACE \brief The QTextLength class encapsulates the different types of length used in a QTextDocument. - \ingroup text + \ingroup richtext-processing When we specify a value for the length of an element in a text document, we often need to provide some other information so that the length is @@ -89,7 +89,7 @@ QT_BEGIN_NAMESPACE /*! \fn Type QTextLength::type() const - Returns the type of length. + Returns the type of this length object. \sa QTextLength::Type */ @@ -129,9 +129,15 @@ QT_BEGIN_NAMESPACE /*! \enum QTextLength::Type - \value VariableLength - \value FixedLength - \value PercentageLength + This enum describes the different types a length object can + have. + + \value VariableLength The width of the object is variable + \value FixedLength The width of the object is fixed + \value PercentageLength The width of the object is in + percentage of the maximum width + + \sa type() */ /*! @@ -142,6 +148,7 @@ QTextLength::operator QVariant() const return QVariant(QVariant::TextLength, this); } +#ifndef QT_NO_DATASTREAM QDataStream &operator<<(QDataStream &stream, const QTextLength &length) { return stream << qint32(length.lengthType) << double(length.fixedValueOrPercentage); @@ -156,6 +163,7 @@ QDataStream &operator>>(QDataStream &stream, QTextLength &length) length.lengthType = QTextLength::Type(type); return stream; } +#endif // QT_NO_DATASTREAM class QTextFormatPrivate : public QSharedData { @@ -259,10 +267,11 @@ private: static uint variantHash(const QVariant &variant) { - switch (variant.type()) { + switch (variant.userType()) { case QVariant::Invalid: return 0; case QVariant::Bool: return variant.toBool(); case QVariant::Int: return variant.toInt(); + case QMetaType::Float: return static_cast<int>(variant.toFloat()); case QVariant::Double: return static_cast<int>(variant.toDouble()); case QVariant::String: return qHash(variant.toString()); case QVariant::Color: return qHash(qvariant_cast<QColor>(variant).rgb()); @@ -317,7 +326,7 @@ void QTextFormatPrivate::recalcFont() const f.setFamily(props.at(i).value.toString()); break; case QTextFormat::FontPointSize: - f.setPointSizeF(props.at(i).value.toDouble()); + f.setPointSizeF(props.at(i).value.toReal()); break; case QTextFormat::FontPixelSize: f.setPixelSize(props.at(i).value.toInt()); @@ -344,10 +353,10 @@ void QTextFormatPrivate::recalcFont() const f.setStrikeOut(props.at(i).value.toBool()); break; case QTextFormat::FontLetterSpacing: - f.setLetterSpacing(QFont::PercentageSpacing, props.at(i).value.toDouble()); + f.setLetterSpacing(QFont::PercentageSpacing, props.at(i).value.toReal()); break; case QTextFormat::FontWordSpacing: - f.setWordSpacing(props.at(i).value.toDouble()); + f.setWordSpacing(props.at(i).value.toReal()); break; case QTextFormat::FontCapitalization: f.setCapitalization(static_cast<QFont::Capitalization> (props.at(i).value.toInt())); @@ -374,6 +383,7 @@ void QTextFormatPrivate::recalcFont() const fontDirty = false; } +#ifndef QT_NO_DATASTREAM Q_GUI_EXPORT QDataStream &operator<<(QDataStream &stream, const QTextFormat &fmt) { stream << fmt.format_type << fmt.properties(); @@ -396,6 +406,7 @@ Q_GUI_EXPORT QDataStream &operator>>(QDataStream &stream, QTextFormat &fmt) return stream; } +#endif // QT_NO_DATASTREAM /*! \class QTextFormat @@ -404,7 +415,7 @@ Q_GUI_EXPORT QDataStream &operator>>(QDataStream &stream, QTextFormat &fmt) \brief The QTextFormat class provides formatting information for a QTextDocument. - \ingroup text + \ingroup richtext-processing \ingroup shared A QTextFormat is a generic class used for describing the format of @@ -413,7 +424,7 @@ Q_GUI_EXPORT QDataStream &operator>>(QDataStream &stream, QTextFormat &fmt) more useful, and describe the formatting that is applied to specific parts of the document. - A format has a \c FormatType which specifies the kinds of thing it + A format has a \c FormatType which specifies the kinds of text item it can format; e.g. a block of text, a list, a table, etc. A format also has various properties (some specific to particular format types), as described by the Property enum. Every property has a @@ -437,30 +448,38 @@ Q_GUI_EXPORT QDataStream &operator>>(QDataStream &stream, QTextFormat &fmt) associate the format with a QTextObject. It is used to represent lists, frames, and tables inside the document. - \sa {Text Processing Classes} + \sa {Rich Text Processing} */ /*! \enum QTextFormat::FormatType - \value InvalidFormat - \value BlockFormat - \value CharFormat - \value ListFormat - \value TableFormat - \value FrameFormat + This enum describes the text item a QTextFormat object is formatting. + + \value InvalidFormat An invalid format as created by the default + constructor + \value BlockFormat The object formats a text block + \value CharFormat The object formats a single character + \value ListFormat The object formats a list + \value TableFormat The object formats a table + \value FrameFormat The object formats a frame \value UserFormat + + \sa QTextCharFormat, QTextBlockFormat, QTextListFormat, + QTextTableFormat, type() */ /*! \enum QTextFormat::Property - \value ObjectIndex + This enum describes the different properties a format can have. + + \value ObjectIndex The index of the formatted object. See objectIndex(). Paragraph and character properties - \value CssFloat + \value CssFloat How a frame is located relative to the surrounding text \value LayoutDirection The layout direction of the text in the document (Qt::LayoutDirection). @@ -478,25 +497,25 @@ Q_GUI_EXPORT QDataStream &operator>>(QDataStream &stream, QTextFormat &fmt) \value BlockRightMargin \value TextIndent \value TabPositions Specifies the tab positions. The tab positions are structs of QTextOption::Tab which are stored in - a QList (internally, in a QList<QVariant>). + a QList (internally, in a QList<QVariant>). \value BlockIndent \value BlockNonBreakableLines - \value BlockTrailingHorizontalRulerWidth + \value BlockTrailingHorizontalRulerWidth The width of a horizontal ruler element. Character properties \value FontFamily \value FontPointSize + \value FontPixelSize \value FontSizeAdjustment Specifies the change in size given to the fontsize already set using FontPointSize or FontPixelSize. + \value FontFixedPitch \omitvalue FontSizeIncrement \value FontWeight \value FontItalic \value FontUnderline \e{This property has been deprecated.} Use QTextFormat::TextUnderlineStyle instead. \value FontOverline \value FontStrikeOut - \value FontFixedPitch - \value FontPixelSize \value FontCapitalization Specifies the capitalization type that is to be applied to the text. \value FontLetterSpacing Changes the default spacing between individual letters in the font. The value is specified in percentage, with 100 as the default value. @@ -508,7 +527,7 @@ Q_GUI_EXPORT QDataStream &operator>>(QDataStream &stream, QTextFormat &fmt) \omitvalue FirstFontProperty \omitvalue LastFontProperty - + \value TextUnderlineColor \value TextVerticalAlignment \value TextOutline @@ -529,7 +548,7 @@ Q_GUI_EXPORT QDataStream &operator>>(QDataStream &stream, QTextFormat &fmt) \value FrameBorder \value FrameBorderBrush - \value FrameBorderStyle + \value FrameBorderStyle See the \l{QTextFrameFormat::BorderStyle}{BorderStyle} enum. \value FrameBottomMargin \value FrameHeight \value FrameLeftMargin @@ -561,33 +580,46 @@ Q_GUI_EXPORT QDataStream &operator>>(QDataStream &stream, QTextFormat &fmt) Selection properties - \value FullWidthSelection When set on the characterFormat of a selection, the whole width of the text will be shown selected + \value FullWidthSelection When set on the characterFormat of a selection, + the whole width of the text will be shown selected. Page break properties - \value PageBreakPolicy + \value PageBreakPolicy Specifies how pages are broken. See the PageBreakFlag enum. \value UserProperty + + \sa property(), setProperty() */ /*! \enum QTextFormat::ObjectTypes + This enum describes what kind of QTextObject this format is associated with. + \value NoObject \value ImageObject \value TableObject \value TableCellObject \value UserObject The first object that can be used for application-specific purposes. + + \sa QTextObject, QTextTable, QTextObject::format() */ /*! \enum QTextFormat::PageBreakFlag \since 4.2 + This enum describes how page breaking is performed when printing. It maps to the + corresponding css properties. + \value PageBreak_Auto The page break is determined automatically depending on the available space on the current page \value PageBreak_AlwaysBefore The page is always broken before the paragraph/table \value PageBreak_AlwaysAfter A new page is always started after the paragraph/table + + \sa QTextBlockFormat::pageBreakPolicy(), QTextFrameFormat::pageBreakPolicy(), + PageBreakPolicy */ /*! @@ -821,7 +853,7 @@ bool QTextFormat::boolProperty(int propertyId) const if (!d) return false; const QVariant prop = d->property(propertyId); - if (prop.type() != QVariant::Bool) + if (prop.userType() != QVariant::Bool) return false; return prop.toBool(); } @@ -837,7 +869,7 @@ int QTextFormat::intProperty(int propertyId) const if (!d) return 0; const QVariant prop = d->property(propertyId); - if (prop.type() != QVariant::Int) + if (prop.userType() != QVariant::Int) return 0; return prop.toInt(); } @@ -854,7 +886,7 @@ qreal QTextFormat::doubleProperty(int propertyId) const if (!d) return 0.; const QVariant prop = d->property(propertyId); - if (prop.type() != QVariant::Double && prop.type() != QMetaType::Float) + if (prop.userType() != QVariant::Double && prop.userType() != QMetaType::Float) return 0.; return qVariantValue<qreal>(prop); } @@ -871,7 +903,7 @@ QString QTextFormat::stringProperty(int propertyId) const if (!d) return QString(); const QVariant prop = d->property(propertyId); - if (prop.type() != QVariant::String) + if (prop.userType() != QVariant::String) return QString(); return prop.toString(); } @@ -889,7 +921,7 @@ QColor QTextFormat::colorProperty(int propertyId) const if (!d) return QColor(); const QVariant prop = d->property(propertyId); - if (prop.type() != QVariant::Color) + if (prop.userType() != QVariant::Color) return QColor(); return qvariant_cast<QColor>(prop); } @@ -906,7 +938,7 @@ QPen QTextFormat::penProperty(int propertyId) const if (!d) return QPen(Qt::NoPen); const QVariant prop = d->property(propertyId); - if (prop.type() != QVariant::Pen) + if (prop.userType() != QVariant::Pen) return QPen(Qt::NoPen); return qvariant_cast<QPen>(prop); } @@ -923,7 +955,7 @@ QBrush QTextFormat::brushProperty(int propertyId) const if (!d) return QBrush(Qt::NoBrush); const QVariant prop = d->property(propertyId); - if (prop.type() != QVariant::Brush) + if (prop.userType() != QVariant::Brush) return QBrush(Qt::NoBrush); return qvariant_cast<QBrush>(prop); } @@ -953,13 +985,13 @@ QVector<QTextLength> QTextFormat::lengthVectorProperty(int propertyId) const if (!d) return vector; const QVariant prop = d->property(propertyId); - if (prop.type() != QVariant::List) + if (prop.userType() != QVariant::List) return vector; QList<QVariant> propertyList = prop.toList(); for (int i=0; i<propertyList.size(); ++i) { QVariant var = propertyList.at(i); - if (var.type() == QVariant::TextLength) + if (var.userType() == QVariant::TextLength) vector.append(qvariant_cast<QTextLength>(var)); } @@ -968,6 +1000,8 @@ QVector<QTextLength> QTextFormat::lengthVectorProperty(int propertyId) const /*! Returns the property specified by the given \a propertyId. + + \sa Property */ QVariant QTextFormat::property(int propertyId) const { @@ -976,6 +1010,8 @@ QVariant QTextFormat::property(int propertyId) const /*! Sets the property specified by the \a propertyId to the given \a value. + + \sa Property */ void QTextFormat::setProperty(int propertyId, const QVariant &value) { @@ -1003,8 +1039,10 @@ void QTextFormat::setProperty(int propertyId, const QVector<QTextLength> &value) } /*! - Clears the value of the property given by \a propertyId - */ + Clears the value of the property given by \a propertyId + + \sa Property +*/ void QTextFormat::clearProperty(int propertyId) { if (!d) @@ -1016,14 +1054,18 @@ void QTextFormat::clearProperty(int propertyId) /*! \fn void QTextFormat::setObjectType(int type) - Sets the text format's object \a type. See \c{ObjectTypes}. + Sets the text format's object type to \a type. + + \sa ObjectTypes, objectType() */ /*! \fn int QTextFormat::objectType() const - Returns the text format's object type. See \c{ObjectTypes}. + Returns the text format's object type. + + \sa ObjectTypes, setObjectType() */ @@ -1037,7 +1079,7 @@ int QTextFormat::objectIndex() const if (!d) return -1; const QVariant prop = d->property(ObjectIndex); - if (prop.type() != QVariant::Int) // #### + if (prop.userType() != QVariant::Int) // #### return -1; return prop.toInt(); } @@ -1142,7 +1184,7 @@ bool QTextFormat::operator==(const QTextFormat &rhs) const \brief The QTextCharFormat class provides formatting information for characters in a QTextDocument. - \ingroup text + \ingroup richtext-processing The character format of text in a document specifies the visual properties of the text, as well as information about its role in a hypertext document. @@ -1613,9 +1655,9 @@ void QTextCharFormat::setUnderlineStyle(UnderlineStyle style) QString QTextCharFormat::anchorName() const { QVariant prop = property(AnchorName); - if (prop.type() == QVariant::StringList) + if (prop.userType() == QVariant::StringList) return prop.toStringList().value(0); - else if (prop.type() != QVariant::String) + else if (prop.userType() != QVariant::String) return QString(); return prop.toString(); } @@ -1631,9 +1673,9 @@ QString QTextCharFormat::anchorName() const QStringList QTextCharFormat::anchorNames() const { QVariant prop = property(AnchorName); - if (prop.type() == QVariant::StringList) + if (prop.userType() == QVariant::StringList) return prop.toStringList(); - else if (prop.type() != QVariant::String) + else if (prop.userType() != QVariant::String) return QStringList(); return QStringList(prop.toString()); } @@ -1755,7 +1797,7 @@ QFont QTextCharFormat::font() const \brief The QTextBlockFormat class provides formatting information for blocks of text in a QTextDocument. - \ingroup text + \ingroup richtext-processing A document is composed of a list of blocks, represented by QTextBlock objects. Each block can contain an item of some kind, such as a @@ -2046,7 +2088,7 @@ QList<QTextOption::Tab> QTextBlockFormat::tabPositions() const \brief The QTextListFormat class provides formatting information for lists in a QTextDocument. - \ingroup text + \ingroup richtext-processing A list is composed of one or more items, represented as text blocks. The list's format specifies the appearance of items in the list. @@ -2075,6 +2117,8 @@ QList<QTextOption::Tab> QTextBlockFormat::tabPositions() const \value ListDecimal decimal values in ascending order \value ListLowerAlpha lower case Latin characters in alphabetical order \value ListUpperAlpha upper case Latin characters in alphabetical order + \value ListLowerRoman lower case roman numerals (supports up to 4999 items only) + \value ListUpperRoman upper case roman numerals (supports up to 4999 items only) \omitvalue ListStyleUndefined */ @@ -2111,17 +2155,17 @@ QTextListFormat::QTextListFormat(const QTextFormat &fmt) /*! \fn void QTextListFormat::setStyle(Style style) - Sets the list format's \a style. See \c{Style} for the available styles. + Sets the list format's \a style. - \sa style() + \sa style() Style */ /*! \fn Style QTextListFormat::style() const - Returns the list format's style. See \c{Style}. + Returns the list format's style. - \sa setStyle() + \sa setStyle() Style */ @@ -2154,7 +2198,7 @@ QTextListFormat::QTextListFormat(const QTextFormat &fmt) \brief The QTextFrameFormat class provides formatting information for frames in a QTextDocument. - \ingroup text + \ingroup richtext-processing A text frame groups together one or more blocks of text, providing a layer of structure larger than the paragraph. The format of a frame specifies @@ -2183,16 +2227,21 @@ QTextListFormat::QTextListFormat(const QTextFormat &fmt) /*! \enum QTextFrameFormat::Position + This enum describes how a frame is located relative to the surrounding text. + \value InFlow \value FloatLeft \value FloatRight + \sa position() CssFloat */ /*! \enum QTextFrameFormat::BorderStyle \since 4.3 + This enum describes different border styles for the text frame. + \value BorderStyle_None \value BorderStyle_Dotted \value BorderStyle_Dashed @@ -2205,6 +2254,7 @@ QTextListFormat::QTextListFormat(const QTextFormat &fmt) \value BorderStyle_Inset \value BorderStyle_Outset + \sa borderStyle() FrameBorderStyle */ /*! @@ -2474,7 +2524,7 @@ qreal QTextFrameFormat::rightMargin() const \brief The QTextTableFormat class provides formatting information for tables in a QTextDocument. - \ingroup text + \ingroup richtext-processing A table is a group of cells ordered into rows and columns. Each table contains at least one row and one column. Each cell contains a block. @@ -2680,7 +2730,7 @@ QTextTableFormat::QTextTableFormat(const QTextFormat &fmt) \brief The QTextImageFormat class provides formatting information for images in a QTextDocument. - \ingroup text + \ingroup richtext-processing Inline images are represented by an object replacement character (0xFFFC in Unicode) which has an associated QTextImageFormat. The @@ -2949,7 +2999,7 @@ QTextTableCellFormat::QTextTableCellFormat(const QTextFormat &fmt) \brief The QTextTableCellFormat class provides formatting information for table cells in a QTextDocument. - \ingroup text + \ingroup richtext-processing The table cell format of a table cell in a document specifies the visual properties of the table cell. @@ -2993,12 +3043,18 @@ int QTextFormatCollection::indexForFormat(const QTextFormat &format) int idx = formats.size(); formats.append(format); - QTextFormat &f = formats.last(); - if (!f.d) - f.d = new QTextFormatPrivate; - f.d->resolveFont(defaultFnt); + QT_TRY{ + QTextFormat &f = formats.last(); + if (!f.d) + f.d = new QTextFormatPrivate; + f.d->resolveFont(defaultFnt); + + hashes.insert(hash); - hashes.insert(hash); + } QT_CATCH(...) { + formats.pop_back(); + QT_RETHROW; + } return idx; } diff --git a/src/gui/text/qtextformat.h b/src/gui/text/qtextformat.h index 4ad13bb..76ab92a 100644 --- a/src/gui/text/qtextformat.h +++ b/src/gui/text/qtextformat.h @@ -1,7 +1,6 @@ /**************************************************************************** ** ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** ** This file is part of the QtGui module of the Qt Toolkit. @@ -21,9 +20,10 @@ ** ensure the GNU Lesser General Public License version 2.1 requirements ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. ** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.1, included in the file LGPL_EXCEPTION.txt in this +** package. ** ** If you have questions regarding the use of this file, please contact ** Nokia at qt-info@nokia.com. @@ -76,8 +76,10 @@ class QTextCursor; class QTextDocument; class QTextLength; +#ifndef QT_NO_DATASTREAM Q_GUI_EXPORT QDataStream &operator<<(QDataStream &, const QTextLength &); Q_GUI_EXPORT QDataStream &operator>>(QDataStream &, QTextLength &); +#endif class Q_GUI_EXPORT QTextLength { @@ -119,8 +121,10 @@ private: inline QTextLength::QTextLength(Type atype, qreal avalue) : lengthType(atype), fixedValueOrPercentage(avalue) {} +#ifndef QT_NO_DATASTREAM Q_GUI_EXPORT QDataStream &operator<<(QDataStream &, const QTextFormat &); Q_GUI_EXPORT QDataStream &operator>>(QDataStream &, QTextFormat &); +#endif class Q_GUI_EXPORT QTextFormat { @@ -600,6 +604,8 @@ public: ListDecimal = -4, ListLowerAlpha = -5, ListUpperAlpha = -6, + ListLowerRoman = -7, + ListUpperRoman = -8, ListStyleUndefined = 0 }; diff --git a/src/gui/text/qtextformat_p.h b/src/gui/text/qtextformat_p.h index c796343..87193ca 100644 --- a/src/gui/text/qtextformat_p.h +++ b/src/gui/text/qtextformat_p.h @@ -1,7 +1,6 @@ /**************************************************************************** ** ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** ** This file is part of the QtGui module of the Qt Toolkit. @@ -21,9 +20,10 @@ ** ensure the GNU Lesser General Public License version 2.1 requirements ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. ** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.1, included in the file LGPL_EXCEPTION.txt in this +** package. ** ** If you have questions regarding the use of this file, please contact ** Nokia at qt-info@nokia.com. diff --git a/src/gui/text/qtexthtmlparser.cpp b/src/gui/text/qtexthtmlparser.cpp index 31d055e..1e2a94c 100644 --- a/src/gui/text/qtexthtmlparser.cpp +++ b/src/gui/text/qtexthtmlparser.cpp @@ -1,7 +1,6 @@ /**************************************************************************** ** ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** ** This file is part of the QtGui module of the Qt Toolkit. @@ -21,9 +20,10 @@ ** ensure the GNU Lesser General Public License version 2.1 requirements ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. ** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.1, included in the file LGPL_EXCEPTION.txt in this +** package. ** ** If you have questions regarding the use of this file, please contact ** Nokia at qt-info@nokia.com. @@ -343,7 +343,7 @@ static QChar resolveEntity(const QString &entity) return e->code; } -static const uint windowsLatin1ExtendedCharacters[0xA0 - 0x80] = { +static const ushort windowsLatin1ExtendedCharacters[0xA0 - 0x80] = { 0x20ac, // 0x80 0x0081, // 0x81 direct mapping 0x201a, // 0x82 @@ -499,7 +499,7 @@ void QTextHtmlParser::dumpHtml() { for (int i = 0; i < count(); ++i) { qDebug().nospace() << qPrintable(QString(depth(i)*4, QLatin1Char(' '))) - << qPrintable(at(i).tag) << ":" + << qPrintable(at(i).tag) << ':' << quoteNewline(at(i).text); ; } @@ -1206,6 +1206,8 @@ void QTextHtmlParserNode::setListStyle(const QVector<QCss::Value> &cssValues) case QCss::Value_Decimal: hasOwnListStyle = true; listStyle = QTextListFormat::ListDecimal; break; case QCss::Value_LowerAlpha: hasOwnListStyle = true; listStyle = QTextListFormat::ListLowerAlpha; break; case QCss::Value_UpperAlpha: hasOwnListStyle = true; listStyle = QTextListFormat::ListUpperAlpha; break; + case QCss::Value_LowerRoman: hasOwnListStyle = true; listStyle = QTextListFormat::ListLowerRoman; break; + case QCss::Value_UpperRoman: hasOwnListStyle = true; listStyle = QTextListFormat::ListUpperRoman; break; default: break; } } @@ -1441,14 +1443,13 @@ static bool setFloatAttribute(qreal *destination, const QString &value) static void setWidthAttribute(QTextLength *width, QString value) { - qreal realVal; bool ok = false; - realVal = value.toDouble(&ok); + qreal realVal = value.toDouble(&ok); if (ok) { *width = QTextLength(QTextLength::FixedLength, realVal); } else { value = value.trimmed(); - if (!value.isEmpty() && value.at(value.length() - 1) == QLatin1Char('%')) { + if (!value.isEmpty() && value.endsWith(QLatin1Char('%'))) { value.chop(1); realVal = value.toDouble(&ok); if (ok) @@ -1540,6 +1541,10 @@ void QTextHtmlParser::applyAttributes(const QStringList &attributes) node->listStyle = QTextListFormat::ListLowerAlpha; } else if (value == QLatin1String("A")) { node->listStyle = QTextListFormat::ListUpperAlpha; + } else if (value == QLatin1String("i")) { + node->listStyle = QTextListFormat::ListLowerRoman; + } else if (value == QLatin1String("I")) { + node->listStyle = QTextListFormat::ListUpperRoman; } else { value = value.toLower(); if (value == QLatin1String("square")) diff --git a/src/gui/text/qtexthtmlparser_p.h b/src/gui/text/qtexthtmlparser_p.h index 63dfcf5..1e87529 100644 --- a/src/gui/text/qtexthtmlparser_p.h +++ b/src/gui/text/qtexthtmlparser_p.h @@ -1,7 +1,6 @@ /**************************************************************************** ** ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** ** This file is part of the QtGui module of the Qt Toolkit. @@ -21,9 +20,10 @@ ** ensure the GNU Lesser General Public License version 2.1 requirements ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. ** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.1, included in the file LGPL_EXCEPTION.txt in this +** package. ** ** If you have questions regarding the use of this file, please contact ** Nokia at qt-info@nokia.com. diff --git a/src/gui/text/qtextimagehandler.cpp b/src/gui/text/qtextimagehandler.cpp index 415cb91..164d210 100644 --- a/src/gui/text/qtextimagehandler.cpp +++ b/src/gui/text/qtextimagehandler.cpp @@ -1,7 +1,6 @@ /**************************************************************************** ** ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** ** This file is part of the QtGui module of the Qt Toolkit. @@ -21,9 +20,10 @@ ** ensure the GNU Lesser General Public License version 2.1 requirements ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. ** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.1, included in the file LGPL_EXCEPTION.txt in this +** package. ** ** If you have questions regarding the use of this file, please contact ** Nokia at qt-info@nokia.com. diff --git a/src/gui/text/qtextimagehandler_p.h b/src/gui/text/qtextimagehandler_p.h index 2f0e775..bc17e9e 100644 --- a/src/gui/text/qtextimagehandler_p.h +++ b/src/gui/text/qtextimagehandler_p.h @@ -1,7 +1,6 @@ /**************************************************************************** ** ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** ** This file is part of the QtGui module of the Qt Toolkit. @@ -21,9 +20,10 @@ ** ensure the GNU Lesser General Public License version 2.1 requirements ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. ** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.1, included in the file LGPL_EXCEPTION.txt in this +** package. ** ** If you have questions regarding the use of this file, please contact ** Nokia at qt-info@nokia.com. @@ -60,7 +60,7 @@ QT_BEGIN_NAMESPACE class QTextImageFormat; -class Q_GUI_EXPORT QTextImageHandler : public QObject, +class QTextImageHandler : public QObject, public QTextObjectInterface { Q_OBJECT @@ -72,7 +72,7 @@ public: virtual void drawObject(QPainter *p, const QRectF &rect, QTextDocument *doc, int posInDocument, const QTextFormat &format); typedef QImage (*ExternalImageLoaderFunction)(const QString &name, const QString &context); - static ExternalImageLoaderFunction externalLoader; + static Q_GUI_EXPORT ExternalImageLoaderFunction externalLoader; //this is needed by Qt3Support }; QT_END_NAMESPACE diff --git a/src/gui/text/qtextlayout.cpp b/src/gui/text/qtextlayout.cpp index 26547f5..60e5296 100644 --- a/src/gui/text/qtextlayout.cpp +++ b/src/gui/text/qtextlayout.cpp @@ -1,7 +1,6 @@ /**************************************************************************** ** ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** ** This file is part of the QtGui module of the Qt Toolkit. @@ -21,9 +20,10 @@ ** ensure the GNU Lesser General Public License version 2.1 requirements ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. ** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.1, included in the file LGPL_EXCEPTION.txt in this +** package. ** ** If you have questions regarding the use of this file, please contact ** Nokia at qt-info@nokia.com. @@ -128,7 +128,7 @@ static QFixed alignLine(QTextEngine *eng, const QScriptLine &line) \brief The QTextInlineObject class represents an inline object in a QTextLayout. - \ingroup text + \ingroup richtext-processing This class is only used if the text layout is used to lay out parts of a QTextDocument. @@ -285,7 +285,7 @@ Qt::LayoutDirection QTextInlineObject::textDirection() const \brief The QTextLayout class is used to lay out and paint a single paragraph of text. - \ingroup text + \ingroup richtext-processing It offers most features expected from a modern text layout engine, including Unicode compliant rendering, line breaking and @@ -367,7 +367,7 @@ QTextLayout::QTextLayout(const QString& text, const QFont &font, QPaintDevice *p QFont f(font); if (paintdevice) f = QFont(font, paintdevice); - d = new QTextEngine((text.isNull() ? (const QString&)QString::fromLatin1("") : text), f.d); + d = new QTextEngine((text.isNull() ? (const QString&)QString::fromLatin1("") : text), f.d.data()); } /*! @@ -1368,7 +1368,7 @@ void QTextLayout::drawCursor(QPainter *p, const QPointF &pos, int cursorPosition \brief The QTextLine class represents a line of text inside a QTextLayout. - \ingroup text + \ingroup richtext-processing A text line is usually created by QTextLayout::createLine(). @@ -1589,27 +1589,54 @@ void QTextLine::setNumColumns(int numColumns, qreal alignmentWidth) #define LB_DEBUG if (0) qDebug #endif -static inline bool checkFullOtherwiseExtend(QScriptLine &line, QScriptLine &tmpData, QScriptLine &spaceData, - int glyphCount, int maxGlyphs, QFixed &minw, bool manualWrap, - QFixed softHyphenWidth = QFixed()) -{ +namespace { + + struct LineBreakHelper + { + LineBreakHelper() : glyphCount(0), maxGlyphs(0), manualWrap(false) {} + + QScriptLine tmpData; + QScriptLine spaceData; + + int glyphCount; + int maxGlyphs; + + QFixed minw; + QFixed softHyphenWidth; + QFixed rightBearing; + + bool manualWrap; + + bool checkFullOtherwiseExtend(QScriptLine &line); + }; + +inline bool LineBreakHelper::checkFullOtherwiseExtend(QScriptLine &line) +{ LB_DEBUG("possible break width %f, spacew=%f", tmpData.textWidth.toReal(), spaceData.textWidth.toReal()); - if (line.length && !manualWrap && - (line.textWidth + tmpData.textWidth + spaceData.textWidth + softHyphenWidth > line.width || glyphCount > maxGlyphs)) + + QFixed newWidth = line.textWidth + tmpData.textWidth + spaceData.textWidth + softHyphenWidth + rightBearing; + if (line.length && !manualWrap && (newWidth > line.width || glyphCount > maxGlyphs)) return true; + minw = qMax(minw, tmpData.textWidth); line += tmpData; line.textWidth += spaceData.textWidth; + line.length += spaceData.length; tmpData.textWidth = 0; tmpData.length = 0; spaceData.textWidth = 0; spaceData.length = 0; + return false; } +} // anonymous namespace + + static inline void addNextCluster(int &pos, int end, QScriptLine &line, int &glyphCount, - const QScriptItem ¤t, const unsigned short *logClusters, const QGlyphLayout &glyphs) + const QScriptItem ¤t, const unsigned short *logClusters, + const QGlyphLayout &glyphs) { int glyphPosition = logClusters[pos]; do { // got to the first next cluster @@ -1642,9 +1669,13 @@ void QTextLine::layout_helper(int maxGlyphs) Q_ASSERT(line.from < eng->layoutData->string.length()); + LineBreakHelper lbh; + + lbh.maxGlyphs = maxGlyphs; + QTextOption::WrapMode wrapMode = eng->option.wrapMode(); bool breakany = (wrapMode == QTextOption::WrapAnywhere); - bool manualWrap = (wrapMode == QTextOption::ManualWrap || wrapMode == QTextOption::NoWrap); + lbh.manualWrap = (wrapMode == QTextOption::ManualWrap || wrapMode == QTextOption::NoWrap); // #### binary search! int item = -1; @@ -1654,12 +1685,7 @@ void QTextLine::layout_helper(int maxGlyphs) break; } - QFixed minw = 0; - int glyphCount = 0; - LB_DEBUG("from: %d: item=%d, total %d, width available %f", line.from, newItem, eng->layoutData->items.size(), line.width.toReal()); - QScriptLine tmpData; - QScriptLine spaceData; Qt::Alignment alignment = eng->option.alignment(); @@ -1668,7 +1694,10 @@ void QTextLine::layout_helper(int maxGlyphs) int end = 0; QGlyphLayout glyphs; const unsigned short *logClusters = eng->layoutData->logClustersPtr; + while (newItem < eng->layoutData->items.size()) { + lbh.rightBearing = 0; + lbh.softHyphenWidth = 0; if (newItem != item) { item = newItem; const QScriptItem ¤t = eng->layoutData->items[item]; @@ -1683,57 +1712,60 @@ void QTextLine::layout_helper(int maxGlyphs) } const QScriptItem ¤t = eng->layoutData->items[item]; - tmpData.ascent = qMax(tmpData.ascent, current.ascent); - tmpData.descent = qMax(tmpData.descent, current.descent); + 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))) { - if (checkFullOtherwiseExtend(line, tmpData, spaceData, glyphCount, maxGlyphs, minw, manualWrap)) + if (lbh.checkFullOtherwiseExtend(line)) goto found; - QFixed x = line.x + line.textWidth + tmpData.textWidth + spaceData.textWidth; - spaceData.textWidth += eng->calculateTabWidth(item, x); - spaceData.length++; + QFixed x = line.x + line.textWidth + lbh.tmpData.textWidth + lbh.spaceData.textWidth; + lbh.spaceData.textWidth += eng->calculateTabWidth(item, x); + lbh.spaceData.length++; newItem = item + 1; - ++glyphCount; - if (checkFullOtherwiseExtend(line, tmpData, spaceData, glyphCount, maxGlyphs, minw, manualWrap)) + ++lbh.glyphCount; + if (lbh.checkFullOtherwiseExtend(line)) goto found; } else if (current.analysis.flags == QScriptAnalysis::LineOrParagraphSeparator) { // if the line consists only of the line separator make sure // we have a sane height - if (!line.length && !tmpData.length) + if (!line.length && !lbh.tmpData.length) line.setDefaultHeight(eng); if (eng->option.flags() & QTextOption::ShowLineAndParagraphSeparators) { - addNextCluster(pos, end, tmpData, glyphCount, current, logClusters, glyphs); + addNextCluster(pos, end, lbh.tmpData, lbh.glyphCount, + current, logClusters, glyphs); } else { - tmpData.length++; + lbh.tmpData.length++; } - line += tmpData; + line += lbh.tmpData; goto found; } else if (current.analysis.flags == QScriptAnalysis::Object) { - tmpData.length++; + lbh.tmpData.length++; QTextFormat format = eng->formats()->format(eng->formatIndex(&eng->layoutData->items[item])); if (eng->block.docHandle()) eng->docLayout()->positionInlineObject(QTextInlineObject(item, eng), eng->block.position() + current.position, format); - tmpData.textWidth += current.width; + lbh.tmpData.textWidth += current.width; newItem = item + 1; - ++glyphCount; - if (checkFullOtherwiseExtend(line, tmpData, spaceData, glyphCount, maxGlyphs, minw, manualWrap)) + ++lbh.glyphCount; + if (lbh.checkFullOtherwiseExtend(line)) goto found; } else if (attributes[pos].whiteSpace) { while (pos < end && attributes[pos].whiteSpace) - addNextCluster(pos, end, spaceData, glyphCount, current, logClusters, glyphs); + addNextCluster(pos, end, lbh.spaceData, lbh.glyphCount, + current, logClusters, glyphs); - if (!manualWrap && spaceData.textWidth > line.width) { - spaceData.textWidth = line.width; // ignore spaces that fall out of the line. + if (!lbh.manualWrap && lbh.spaceData.textWidth > line.width) { + lbh.spaceData.textWidth = line.width; // ignore spaces that fall out of the line. goto found; } } else { bool sb_or_ws = false; do { - addNextCluster(pos, end, tmpData, glyphCount, current, logClusters, glyphs); + addNextCluster(pos, end, lbh.tmpData, lbh.glyphCount, + current, logClusters, glyphs); if (attributes[pos].whiteSpace || attributes[pos-1].lineBreakType != HB_NoBreak) { sb_or_ws = true; @@ -1742,9 +1774,8 @@ void QTextLine::layout_helper(int maxGlyphs) break; } } while (pos < end); - minw = qMax(tmpData.textWidth, minw); + lbh.minw = qMax(lbh.tmpData.textWidth, lbh.minw); - QFixed softHyphenWidth; if (pos && attributes[pos - 1].lineBreakType == HB_SoftHyphen) { // if we are splitting up a word because of // a soft hyphen then we ... @@ -1763,16 +1794,29 @@ void QTextLine::layout_helper(int maxGlyphs) // and thus become invisible again. // if (line.length) - softHyphenWidth = glyphs.advances_x[logClusters[pos - 1]]; + lbh.softHyphenWidth = glyphs.advances_x[logClusters[pos - 1]]; else if (breakany) - tmpData.textWidth += glyphs.advances_x[logClusters[pos - 1]]; + lbh.tmpData.textWidth += glyphs.advances_x[logClusters[pos - 1]]; } - if ((sb_or_ws|breakany) - && checkFullOtherwiseExtend(line, tmpData, spaceData, glyphCount, maxGlyphs, minw, manualWrap, softHyphenWidth)) { + // The actual width of the text needs to take the right bearing into account. The + // right bearing is left-ward, which means that if the rightmost pixel is to the right + // of the advance of the glyph, the bearing will be negative. We flip the sign + // for the code to be more readable. Logic borrowed from qfontmetrics.cpp. + if (pos) { + QFontEngine *fontEngine = eng->fontEngine(current); + glyph_t glyph = glyphs.glyphs[logClusters[pos - 1]]; + glyph_metrics_t gi = fontEngine->boundingBox(glyph); + lbh.rightBearing = -qRound(gi.xoff - gi.x - gi.width); + } + + if ((sb_or_ws|breakany) && lbh.checkFullOtherwiseExtend(line)) { if (!breakany) { - line.textWidth += softHyphenWidth; + line.textWidth += lbh.softHyphenWidth; } + + line.textWidth += lbh.rightBearing; + goto found; } } @@ -1780,45 +1824,48 @@ void QTextLine::layout_helper(int maxGlyphs) newItem = item + 1; } LB_DEBUG("reached end of line"); - checkFullOtherwiseExtend(line, tmpData, spaceData, glyphCount, maxGlyphs, minw, manualWrap); -found: + lbh.checkFullOtherwiseExtend(line); + line.textWidth += lbh.rightBearing; + +found: if (line.length == 0) { LB_DEBUG("no break available in line, adding temp: length %d, width %f, space: length %d, width %f", - tmpData.length, tmpData.textWidth.toReal(), spaceData.length, spaceData.textWidth.toReal()); - line += tmpData; + lbh.tmpData.length, lbh.tmpData.textWidth.toReal(), + lbh.spaceData.length, lbh.spaceData.textWidth.toReal()); + line += lbh.tmpData; } LB_DEBUG("line length = %d, ascent=%f, descent=%f, textWidth=%f (spacew=%f)", line.length, line.ascent.toReal(), - line.descent.toReal(), line.textWidth.toReal(), spaceData.width.toReal()); + line.descent.toReal(), line.textWidth.toReal(), lbh.spaceData.width.toReal()); LB_DEBUG(" : '%s'", eng->layoutData->string.mid(line.from, line.length).toUtf8().data()); - if (manualWrap) { + if (lbh.manualWrap) { eng->minWidth = qMax(eng->minWidth, line.textWidth); eng->maxWidth = qMax(eng->maxWidth, line.textWidth); } else { - eng->minWidth = qMax(eng->minWidth, minw); + eng->minWidth = qMax(eng->minWidth, lbh.minw); eng->maxWidth += line.textWidth; } if (line.textWidth > 0 && item < eng->layoutData->items.size()) - eng->maxWidth += spaceData.textWidth; + eng->maxWidth += lbh.spaceData.textWidth; if (eng->option.flags() & QTextOption::IncludeTrailingSpaces) - line.textWidth += spaceData.textWidth; - line.length += spaceData.length; - if (spaceData.length) + line.textWidth += lbh.spaceData.textWidth; + line.length += lbh.spaceData.length; + if (lbh.spaceData.length) line.hasTrailingSpaces = true; line.justified = false; line.gridfitted = false; if (eng->option.wrapMode() == QTextOption::WrapAtWordBoundaryOrAnywhere) { - if ((maxGlyphs != INT_MAX && glyphCount > maxGlyphs) - || (maxGlyphs == INT_MAX && line.textWidth > line.width)) { + if ((lbh.maxGlyphs != INT_MAX && lbh.glyphCount > lbh.maxGlyphs) + || (lbh.maxGlyphs == INT_MAX && line.textWidth > line.width)) { eng->option.setWrapMode(QTextOption::WrapAnywhere); line.length = 0; line.textWidth = 0; - layout_helper(maxGlyphs); + layout_helper(lbh.maxGlyphs); eng->option.setWrapMode(QTextOption::WrapAtWordBoundaryOrAnywhere); } } diff --git a/src/gui/text/qtextlayout.h b/src/gui/text/qtextlayout.h index 90afac8..d70915a 100644 --- a/src/gui/text/qtextlayout.h +++ b/src/gui/text/qtextlayout.h @@ -1,7 +1,6 @@ /**************************************************************************** ** ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** ** This file is part of the QtGui module of the Qt Toolkit. @@ -21,9 +20,10 @@ ** ensure the GNU Lesser General Public License version 2.1 requirements ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. ** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.1, included in the file LGPL_EXCEPTION.txt in this +** package. ** ** If you have questions regarding the use of this file, please contact ** Nokia at qt-info@nokia.com. diff --git a/src/gui/text/qtextlist.cpp b/src/gui/text/qtextlist.cpp index 4fe27a7..73ec40f 100644 --- a/src/gui/text/qtextlist.cpp +++ b/src/gui/text/qtextlist.cpp @@ -1,7 +1,6 @@ /**************************************************************************** ** ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** ** This file is part of the QtGui module of the Qt Toolkit. @@ -21,9 +20,10 @@ ** ensure the GNU Lesser General Public License version 2.1 requirements ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. ** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.1, included in the file LGPL_EXCEPTION.txt in this +** package. ** ** If you have questions regarding the use of this file, please contact ** Nokia at qt-info@nokia.com. @@ -63,7 +63,7 @@ public: \brief The QTextList class provides a decorated list of items in a QTextDocument. - \ingroup text + \ingroup richtext-processing A list contains a sequence of text blocks, each of which is marked with a bullet point or other symbol. Multiple levels of lists can be used, and @@ -129,8 +129,6 @@ QTextList::~QTextList() /*! Returns the number of items in the list. - - \sa isEmpty() */ int QTextList::count() const { @@ -212,6 +210,55 @@ QString QTextList::itemText(const QTextBlock &blockIt) const } } break; + case QTextListFormat::ListLowerRoman: + case QTextListFormat::ListUpperRoman: + { + if (item < 5000) { + QByteArray romanNumeral; + + // works for up to 4999 items + static const char romanSymbolsLower[] = "iiivixxxlxcccdcmmmm"; + static const char romanSymbolsUpper[] = "IIIVIXXXLXCCCDCMMMM"; + QByteArray romanSymbols; // wrap to have "mid" + if (style == QTextListFormat::ListLowerRoman) + romanSymbols = QByteArray::fromRawData(romanSymbolsLower, sizeof(romanSymbolsLower)); + else + romanSymbols = QByteArray::fromRawData(romanSymbolsUpper, sizeof(romanSymbolsUpper)); + + int c[] = { 1, 4, 5, 9, 10, 40, 50, 90, 100, 400, 500, 900, 1000 }; + int n = item; + for (int i = 12; i >= 0; n %= c[i], i--) { + int q = n / c[i]; + if (q > 0) { + int startDigit = i + (i+3)/4; + int numDigits; + if (i % 4) { + // c[i] == 4|5|9|40|50|90|400|500|900 + if ((i-2) % 4) { + // c[i] == 4|9|40|90|400|900 => with substraction (IV, IX, XL, XC, ...) + numDigits = 2; + } + else { + // c[i] == 5|50|500 (V, L, D) + numDigits = 1; + } + } + else { + // c[i] == 1|10|100|1000 (I, II, III, X, XX, ...) + numDigits = q; + } + + romanNumeral.append(romanSymbols.mid(startDigit, numDigits)); + } + } + result = QString::fromLatin1(romanNumeral); + } + else { + result = QLatin1String("?"); + } + + } + break; default: Q_ASSERT(false); } diff --git a/src/gui/text/qtextlist.h b/src/gui/text/qtextlist.h index 49a7110..4becef6 100644 --- a/src/gui/text/qtextlist.h +++ b/src/gui/text/qtextlist.h @@ -1,7 +1,6 @@ /**************************************************************************** ** ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** ** This file is part of the QtGui module of the Qt Toolkit. @@ -21,9 +20,10 @@ ** ensure the GNU Lesser General Public License version 2.1 requirements ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. ** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.1, included in the file LGPL_EXCEPTION.txt in this +** package. ** ** If you have questions regarding the use of this file, please contact ** Nokia at qt-info@nokia.com. diff --git a/src/gui/text/qtextobject.cpp b/src/gui/text/qtextobject.cpp index 0c21fc1..03da6cd 100644 --- a/src/gui/text/qtextobject.cpp +++ b/src/gui/text/qtextobject.cpp @@ -1,7 +1,6 @@ /**************************************************************************** ** ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** ** This file is part of the QtGui module of the Qt Toolkit. @@ -21,9 +20,10 @@ ** ensure the GNU Lesser General Public License version 2.1 requirements ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. ** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.1, included in the file LGPL_EXCEPTION.txt in this +** package. ** ** If you have questions regarding the use of this file, please contact ** Nokia at qt-info@nokia.com. @@ -61,7 +61,7 @@ QT_BEGIN_NAMESPACE \brief The QTextObject class is a base class for different kinds of objects that can group parts of a QTextDocument together. - \ingroup text + \ingroup richtext-processing The common grouping text objects are lists (QTextList), frames (QTextFrame), and tables (QTextTable). A text object has an @@ -183,7 +183,7 @@ QTextDocumentPrivate *QTextObject::docHandle() const \brief The QTextBlockGroup class provides a container for text blocks within a QTextDocument. - \ingroup text + \ingroup richtext-processing Block groups can be used to organize blocks of text within a document. They maintain an up-to-date list of the text blocks that belong to @@ -305,7 +305,7 @@ QTextFrameLayoutData::~QTextFrameLayoutData() \brief The QTextFrame class represents a frame in a QTextDocument. - \ingroup text + \ingroup richtext-processing Text frames provide structure for the text in a document. They are used as generic containers for other document elements. @@ -599,7 +599,7 @@ void QTextFramePrivate::remove_me() \brief The iterator class provides an iterator for reading the contents of a QTextFrame. - \ingroup text + \ingroup richtext-processing A frame consists of an arbitrary sequence of \l{QTextBlock}s and child \l{QTextFrame}s. This class provides a way to iterate over the @@ -799,7 +799,7 @@ QTextFrame::iterator &QTextFrame::iterator::operator--() \brief The QTextBlockUserData class is used to associate custom data with blocks of text. \since 4.1 - \ingroup text + \ingroup richtext-processing QTextBlockUserData provides an abstract interface for container classes that are used to associate application-specific user data with text blocks in a QTextDocument. @@ -829,7 +829,7 @@ QTextBlockUserData::~QTextBlockUserData() \brief The QTextBlock class provides a container for text fragments in a QTextDocument. - \ingroup text + \ingroup richtext-processing A text block encapsulates a block or paragraph of text in a QTextDocument. QTextBlock provides read-only access to the block/paragraph structure of @@ -924,7 +924,7 @@ QTextBlockUserData::~QTextBlockUserData() \brief The QTextBlock::iterator class provides an iterator for reading the contents of a QTextBlock. - \ingroup text + \ingroup richtext-processing A block consists of a sequence of text fragments. This class provides a way to iterate over these, and read their contents. It does not provide @@ -1525,7 +1525,7 @@ QTextBlock::iterator &QTextBlock::iterator::operator--() \brief The QTextFragment class holds a piece of text in a QTextDocument with a single QTextCharFormat. - \ingroup text + \ingroup richtext-processing A text fragment describes a piece of text that is stored with a single character format. Text in which the character format changes can be diff --git a/src/gui/text/qtextobject.h b/src/gui/text/qtextobject.h index 9bdc6a6..b7d1458 100644 --- a/src/gui/text/qtextobject.h +++ b/src/gui/text/qtextobject.h @@ -1,7 +1,6 @@ /**************************************************************************** ** ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** ** This file is part of the QtGui module of the Qt Toolkit. @@ -21,9 +20,10 @@ ** ensure the GNU Lesser General Public License version 2.1 requirements ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. ** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.1, included in the file LGPL_EXCEPTION.txt in this +** package. ** ** If you have questions regarding the use of this file, please contact ** Nokia at qt-info@nokia.com. diff --git a/src/gui/text/qtextobject_p.h b/src/gui/text/qtextobject_p.h index e9a990e..83f2523 100644 --- a/src/gui/text/qtextobject_p.h +++ b/src/gui/text/qtextobject_p.h @@ -1,7 +1,6 @@ /**************************************************************************** ** ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** ** This file is part of the QtGui module of the Qt Toolkit. @@ -21,9 +20,10 @@ ** ensure the GNU Lesser General Public License version 2.1 requirements ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. ** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.1, included in the file LGPL_EXCEPTION.txt in this +** package. ** ** If you have questions regarding the use of this file, please contact ** Nokia at qt-info@nokia.com. @@ -94,8 +94,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(0), layoutData(0) { } virtual void fragmentAdded(const QChar &type, uint fragment); diff --git a/src/gui/text/qtextodfwriter.cpp b/src/gui/text/qtextodfwriter.cpp index b631a33..ff3d85b 100644 --- a/src/gui/text/qtextodfwriter.cpp +++ b/src/gui/text/qtextodfwriter.cpp @@ -1,7 +1,6 @@ /**************************************************************************** ** ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** ** This file is part of the QtGui module of the Qt Toolkit. @@ -21,9 +20,10 @@ ** ensure the GNU Lesser General Public License version 2.1 requirements ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. ** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.1, included in the file LGPL_EXCEPTION.txt in this +** package. ** ** If you have questions regarding the use of this file, please contact ** Nokia at qt-info@nokia.com. @@ -174,6 +174,10 @@ static QString bulletChar(QTextListFormat::Style style) return QString::fromLatin1("a"); case QTextListFormat::ListUpperAlpha: return QString::fromLatin1("A"); + case QTextListFormat::ListLowerRoman: + return QString::fromLatin1("i"); + case QTextListFormat::ListUpperRoman: + return QString::fromLatin1("I"); default: case QTextListFormat::ListStyleUndefined: return QString(); @@ -295,28 +299,13 @@ void QTextOdfWriter::writeBlock(QXmlStreamWriter &writer, const QTextBlock &bloc writer.writeAttribute(textNS, QString::fromLatin1("style-name"), QString::fromLatin1("c%1") .arg(frag.fragment().charFormatIndex())); bool escapeNextSpace = true; - int precedingSpaces = 0, precedingTabs = 0; + int precedingSpaces = 0; int exportedIndex = 0; for (int i=0; i <= fragmentText.count(); ++i) { - bool isTab = false, isSpace = false; - if (i < fragmentText.count()) { + bool isSpace = false; QChar character = fragmentText[i]; - isTab = character.unicode() == '\t'; isSpace = character.unicode() == ' '; - if (character.unicode() == 0x2028) { // soft-return - writer.writeCharacters(fragmentText.mid(exportedIndex, i)); - writer.writeEmptyElement(textNS, QString::fromLatin1("line-break")); - exportedIndex = i+1; - continue; - } - if (isSpace) { - ++precedingSpaces; - escapeNextSpace = true; - } - else if (isTab) { - precedingTabs++; - } - } + // find more than one space. -> <text:s text:c="2" /> if (!isSpace && escapeNextSpace && precedingSpaces > 1) { const bool startParag = exportedIndex == 0 && i == precedingSpaces; @@ -329,17 +318,27 @@ void QTextOdfWriter::writeBlock(QXmlStreamWriter &writer, const QTextBlock &bloc precedingSpaces = 0; exportedIndex = i; } - // find tabs. -> <text:tab text:tab-ref="3" /> or <text:tab/> - if (!isTab && precedingTabs) { - writer.writeCharacters(fragmentText.mid(exportedIndex, i - precedingTabs - exportedIndex)); - writer.writeEmptyElement(textNS, QString::fromLatin1("tab")); - if (precedingTabs > 1) - writer.writeAttribute(textNS, QString::fromLatin1("tab-ref"), QString::number(precedingTabs)); - precedingTabs = 0; - exportedIndex = i; + + if (i < fragmentText.count()) { + if (character.unicode() == 0x2028) { // soft-return + //if (exportedIndex < i) + writer.writeCharacters(fragmentText.mid(exportedIndex, i - exportedIndex)); + writer.writeEmptyElement(textNS, QString::fromLatin1("line-break")); + exportedIndex = i+1; + continue; + } else if (character.unicode() == '\t') { // Tab + //if (exportedIndex < i) + writer.writeCharacters(fragmentText.mid(exportedIndex, i - exportedIndex)); + writer.writeEmptyElement(textNS, QString::fromLatin1("tab")); + exportedIndex = i+1; + precedingSpaces = 0; + } else if (isSpace) { + ++precedingSpaces; + escapeNextSpace = true; + } else if (!isSpace) { + precedingSpaces = 0; + } } - if (!isSpace && !isTab) - precedingSpaces = 0; } writer.writeCharacters(fragmentText.mid(exportedIndex)); @@ -477,7 +476,7 @@ void QTextOdfWriter::writeBlockFormat(QXmlStreamWriter &writer, QTextBlockFormat if (format.hasProperty(QTextFormat::BlockRightMargin)) writer.writeAttribute(foNS, QString::fromLatin1("margin-right"), pixelToPoint(qMax(qreal(0.), format.rightMargin())) ); if (format.hasProperty(QTextFormat::TextIndent)) - writer.writeAttribute(foNS, QString::fromLatin1("text-indent"), QString::number(format.textIndent())); + writer.writeAttribute(foNS, QString::fromLatin1("text-indent"), pixelToPoint(format.textIndent())); if (format.hasProperty(QTextFormat::PageBreakPolicy)) { if (format.pageBreakPolicy() & QTextFormat::PageBreak_AlwaysBefore) writer.writeAttribute(foNS, QString::fromLatin1("break-before"), QString::fromLatin1("page")); @@ -624,7 +623,9 @@ void QTextOdfWriter::writeListFormat(QXmlStreamWriter &writer, QTextListFormat f QTextListFormat::Style style = format.style(); if (style == QTextListFormat::ListDecimal || style == QTextListFormat::ListLowerAlpha - || style == QTextListFormat::ListUpperAlpha) { + || style == QTextListFormat::ListUpperAlpha + || style == QTextListFormat::ListLowerRoman + || style == QTextListFormat::ListUpperRoman) { writer.writeStartElement(textNS, QString::fromLatin1("list-level-style-number")); writer.writeAttribute(styleNS, QString::fromLatin1("num-format"), bulletChar(style)); writer.writeAttribute(styleNS, QString::fromLatin1("num-suffix"), QString::fromLatin1(".")); diff --git a/src/gui/text/qtextodfwriter_p.h b/src/gui/text/qtextodfwriter_p.h index de59721..001cb46 100644 --- a/src/gui/text/qtextodfwriter_p.h +++ b/src/gui/text/qtextodfwriter_p.h @@ -1,7 +1,6 @@ /**************************************************************************** ** ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** ** This file is part of the QtGui module of the Qt Toolkit. @@ -21,9 +20,10 @@ ** ensure the GNU Lesser General Public License version 2.1 requirements ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. ** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.1, included in the file LGPL_EXCEPTION.txt in this +** package. ** ** If you have questions regarding the use of this file, please contact ** Nokia at qt-info@nokia.com. diff --git a/src/gui/text/qtextoption.cpp b/src/gui/text/qtextoption.cpp index f934e87..616e76a 100644 --- a/src/gui/text/qtextoption.cpp +++ b/src/gui/text/qtextoption.cpp @@ -1,7 +1,6 @@ /**************************************************************************** ** ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** ** This file is part of the QtGui module of the Qt Toolkit. @@ -21,9 +20,10 @@ ** ensure the GNU Lesser General Public License version 2.1 requirements ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. ** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.1, included in the file LGPL_EXCEPTION.txt in this +** package. ** ** If you have questions regarding the use of this file, please contact ** Nokia at qt-info@nokia.com. @@ -117,7 +117,13 @@ QTextOption &QTextOption::operator=(const QTextOption &o) { if (this == &o) return *this; - delete d; d = 0; + + QTextOptionPrivate* dNew = 0; + if (o.d) + dNew = new QTextOptionPrivate(*o.d); + delete d; + d = dNew; + align = o.align; wordWrap = o.wordWrap; design = o.design; @@ -125,8 +131,6 @@ QTextOption &QTextOption::operator=(const QTextOption &o) unused = o.unused; f = o.f; tab = o.tab; - if (o.d) - d = new QTextOptionPrivate(*o.d); return *this; } @@ -197,7 +201,7 @@ QList<QTextOption::Tab> QTextOption::tabs() const \brief The QTextOption class provides a description of general rich text properties. - \ingroup text + \ingroup richtext-processing QTextOption is used to encapsulate common rich text properties in a single object. It contains information about text alignment, layout direction, diff --git a/src/gui/text/qtextoption.h b/src/gui/text/qtextoption.h index 62800e6..d0ead7b 100644 --- a/src/gui/text/qtextoption.h +++ b/src/gui/text/qtextoption.h @@ -1,7 +1,6 @@ /**************************************************************************** ** ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** ** This file is part of the QtGui module of the Qt Toolkit. @@ -21,9 +20,10 @@ ** ensure the GNU Lesser General Public License version 2.1 requirements ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. ** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.1, included in the file LGPL_EXCEPTION.txt in this +** package. ** ** If you have questions regarding the use of this file, please contact ** Nokia at qt-info@nokia.com. diff --git a/src/gui/text/qtexttable.cpp b/src/gui/text/qtexttable.cpp index 418b9b8..3f61e300 100644 --- a/src/gui/text/qtexttable.cpp +++ b/src/gui/text/qtexttable.cpp @@ -1,7 +1,6 @@ /**************************************************************************** ** ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** ** This file is part of the QtGui module of the Qt Toolkit. @@ -21,9 +20,10 @@ ** ensure the GNU Lesser General Public License version 2.1 requirements ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. ** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.1, included in the file LGPL_EXCEPTION.txt in this +** package. ** ** If you have questions regarding the use of this file, please contact ** Nokia at qt-info@nokia.com. @@ -58,7 +58,7 @@ QT_BEGIN_NAMESPACE \brief The QTextTableCell class represents the properties of a cell in a QTextTable. - \ingroup text + \ingroup richtext-processing Table cells are pieces of document structure that belong to a table. The table orders cells into particular rows and columns; cells can @@ -432,6 +432,13 @@ void QTextTablePrivate::fragmentRemoved(const QChar &type, uint fragment) QTextFramePrivate::fragmentRemoved(type, fragment); } +/*! + /fn void QTextTablePrivate::update() const + + This function is usually called when the table is "dirty". + It seems to update all kind of table information. + +*/ void QTextTablePrivate::update() const { Q_Q(const QTextTable); @@ -439,7 +446,7 @@ void QTextTablePrivate::update() const nRows = (cells.size() + nCols-1)/nCols; // qDebug(">>>> QTextTablePrivate::update, nRows=%d, nCols=%d", nRows, nCols); - grid = (int *)realloc(grid, nRows*nCols*sizeof(int)); + grid = q_check_ptr((int *)realloc(grid, nRows*nCols*sizeof(int))); memset(grid, 0, nRows*nCols*sizeof(int)); QTextDocumentPrivate *p = pieceTable; @@ -463,7 +470,7 @@ void QTextTablePrivate::update() const cellIndices[i] = cell; if (r + rowspan > nRows) { - grid = (int *)realloc(grid, sizeof(int)*(r + rowspan)*nCols); + grid = q_check_ptr((int *)realloc(grid, sizeof(int)*(r + rowspan)*nCols)); memset(grid + (nRows*nCols), 0, sizeof(int)*(r+rowspan-nRows)*nCols); nRows = r + rowspan; } @@ -492,7 +499,7 @@ void QTextTablePrivate::update() const \brief The QTextTable class represents a table in a QTextDocument. - \ingroup text + \ingroup richtext-processing A table is a group of cells ordered into rows and columns. Each table contains at least one row and one column. Each cell contains a block, and diff --git a/src/gui/text/qtexttable.h b/src/gui/text/qtexttable.h index d887f41..5715546 100644 --- a/src/gui/text/qtexttable.h +++ b/src/gui/text/qtexttable.h @@ -1,7 +1,6 @@ /**************************************************************************** ** ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** ** This file is part of the QtGui module of the Qt Toolkit. @@ -21,9 +20,10 @@ ** ensure the GNU Lesser General Public License version 2.1 requirements ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. ** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.1, included in the file LGPL_EXCEPTION.txt in this +** package. ** ** If you have questions regarding the use of this file, please contact ** Nokia at qt-info@nokia.com. diff --git a/src/gui/text/qtexttable_p.h b/src/gui/text/qtexttable_p.h index d363b8f..15f8aef 100644 --- a/src/gui/text/qtexttable_p.h +++ b/src/gui/text/qtexttable_p.h @@ -1,7 +1,6 @@ /**************************************************************************** ** ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** ** This file is part of the QtGui module of the Qt Toolkit. @@ -21,9 +20,10 @@ ** ensure the GNU Lesser General Public License version 2.1 requirements ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. ** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.1, included in the file LGPL_EXCEPTION.txt in this +** package. ** ** If you have questions regarding the use of this file, please contact ** Nokia at qt-info@nokia.com. @@ -62,7 +62,7 @@ class QTextTablePrivate : public QTextFramePrivate { Q_DECLARE_PUBLIC(QTextTable) public: - QTextTablePrivate(QTextDocument *document) : QTextFramePrivate(document), grid(0), nRows(0), dirty(true), blockFragmentUpdates(false) {} + QTextTablePrivate(QTextDocument *document) : QTextFramePrivate(document), grid(0), 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/qzip.cpp b/src/gui/text/qzip.cpp index 3b16c3a..b01fdb1 100644 --- a/src/gui/text/qzip.cpp +++ b/src/gui/text/qzip.cpp @@ -1,7 +1,6 @@ /**************************************************************************** ** ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** ** This file is part of the QtGui module of the Qt Toolkit. @@ -21,9 +20,10 @@ ** ensure the GNU Lesser General Public License version 2.1 requirements ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. ** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.1, included in the file LGPL_EXCEPTION.txt in this +** package. ** ** If you have questions regarding the use of this file, please contact ** Nokia at qt-info@nokia.com. @@ -56,13 +56,23 @@ #if defined(Q_OS_WIN) #undef S_IFREG #define S_IFREG 0100000 -# define S_ISDIR(x) ((x) & 0040000) > 0 -# define S_ISREG(x) ((x) & 0170000) == S_IFREG +# ifndef S_ISDIR +# define S_ISDIR(x) ((x) & 0040000) > 0 +# endif +# ifndef S_ISREG +# define S_ISREG(x) ((x) & 0170000) == S_IFREG +# endif # define S_IFLNK 020000 # define S_ISLNK(x) ((x) & S_IFLNK) > 0 -# define S_IRUSR 0400 -# define S_IWUSR 0200 -# define S_IXUSR 0100 +# ifndef S_IRUSR +# define S_IRUSR 0400 +# endif +# ifndef S_IWUSR +# define S_IWUSR 0200 +# endif +# ifndef S_IXUSR +# define S_IXUSR 0100 +# endif # define S_IRGRP 0040 # define S_IWGRP 0020 # define S_IXGRP 0010 @@ -695,7 +705,7 @@ void QZipWriterPrivate::addEntry(EntryType type, const QString &fileName, const */ QZipReader::QZipReader(const QString &archive, QIODevice::OpenMode mode) { - QFile *f = new QFile(archive); + QScopedPointer<QFile> f(new QFile(archive)); f->open(mode); QZipReader::Status status; if (f->error() == QFile::NoError) @@ -711,7 +721,8 @@ QZipReader::QZipReader(const QString &archive, QIODevice::OpenMode mode) status = FileError; } - d = new QZipReaderPrivate(f, /*ownDevice=*/true); + d = new QZipReaderPrivate(f.data(), /*ownDevice=*/true); + f.take(); d->status = status; } @@ -761,7 +772,7 @@ QList<QZipReader::FileInfo> QZipReader::fileInfoList() const { d->scanFiles(); QList<QZipReader::FileInfo> files; - for (int i = 0; d && i < d->fileHeaders.size(); ++i) { + for (int i = 0; i < d->fileHeaders.size(); ++i) { QZipReader::FileInfo fi; d->fillFileInfo(i, fi); files.append(fi); @@ -969,7 +980,7 @@ void QZipReader::close() */ QZipWriter::QZipWriter(const QString &fileName, QIODevice::OpenMode mode) { - QFile *f = new QFile(fileName); + QScopedPointer<QFile> f(new QFile(fileName)); f->open(mode); QZipWriter::Status status; if (f->error() == QFile::NoError) @@ -985,7 +996,8 @@ QZipWriter::QZipWriter(const QString &fileName, QIODevice::OpenMode mode) status = QZipWriter::FileError; } - d = new QZipWriterPrivate(f, /*ownDevice=*/true); + d = new QZipWriterPrivate(f.data(), /*ownDevice=*/true); + f.take(); d->status = status; } diff --git a/src/gui/text/qzipreader_p.h b/src/gui/text/qzipreader_p.h index 51546e8..2e3e241 100644 --- a/src/gui/text/qzipreader_p.h +++ b/src/gui/text/qzipreader_p.h @@ -1,7 +1,6 @@ /**************************************************************************** ** ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** ** This file is part of the QtGui module of the Qt Toolkit. @@ -21,9 +20,10 @@ ** ensure the GNU Lesser General Public License version 2.1 requirements ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. ** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.1, included in the file LGPL_EXCEPTION.txt in this +** package. ** ** If you have questions regarding the use of this file, please contact ** Nokia at qt-info@nokia.com. diff --git a/src/gui/text/qzipwriter_p.h b/src/gui/text/qzipwriter_p.h index 55b1467..e7377aa 100644 --- a/src/gui/text/qzipwriter_p.h +++ b/src/gui/text/qzipwriter_p.h @@ -1,7 +1,6 @@ /**************************************************************************** ** ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** ** This file is part of the QtGui module of the Qt Toolkit. @@ -21,9 +20,10 @@ ** ensure the GNU Lesser General Public License version 2.1 requirements ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. ** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.1, included in the file LGPL_EXCEPTION.txt in this +** package. ** ** If you have questions regarding the use of this file, please contact ** Nokia at qt-info@nokia.com. diff --git a/src/gui/text/text.pri b/src/gui/text/text.pri index fc33d43..b28ecd7 100644 --- a/src/gui/text/text.pri +++ b/src/gui/text/text.pri @@ -106,9 +106,27 @@ embedded { DEFINES += QT_NO_FONTCONFIG } +symbian { + SOURCES += \ + text/qfont_s60.cpp + contains(QT_CONFIG, freetype) { + SOURCES += \ + text/qfontengine_ft.cpp + HEADERS += \ + text/qfontengine_ft_p.h + DEFINES += \ + QT_NO_FONTCONFIG + } else { + SOURCES += \ + text/qfontengine_s60.cpp + HEADERS += \ + text/qfontengine_s60_p.h + LIBS += -lfntstr -lecom + } +} + contains(QT_CONFIG, freetype) { SOURCES += \ - ../3rdparty/freetype/builds/unix/ftsystem.c \ ../3rdparty/freetype/src/base/ftbase.c \ ../3rdparty/freetype/src/base/ftbbox.c \ ../3rdparty/freetype/src/base/ftdebug.c \ @@ -152,10 +170,19 @@ contains(QT_CONFIG, freetype) { ../3rdparty/freetype/src/autofit/afloader.c\ ../3rdparty/freetype/src/autofit/autofit.c + symbian { + SOURCES += \ + ../3rdparty/freetype/src/base/ftsystem.c + } else { + SOURCES += \ + ../3rdparty/freetype/builds/unix/ftsystem.c + INCLUDEPATH += \ + ../3rdparty/freetype/builds/unix + } + INCLUDEPATH += \ ../3rdparty/freetype/src \ - ../3rdparty/freetype/include \ - ../3rdparty/freetype/builds/unix + ../3rdparty/freetype/include DEFINES += FT2_BUILD_LIBRARY FT_CONFIG_OPTION_SYSTEM_ZLIB @@ -164,7 +191,7 @@ contains(QT_CONFIG, freetype) { embedded:CONFIG += opentype # pull in the proper freetype2 include directory include($$QT_SOURCE_TREE/config.tests/unix/freetype/freetype.pri) - LIBS += -lfreetype + LIBS_PRIVATE += -lfreetype } else { DEFINES *= QT_NO_FREETYPE } |