Changeset 561 for trunk/src/gui/text


Ignore:
Timestamp:
Feb 11, 2010, 11:19:06 PM (15 years ago)
Author:
Dmitry A. Kuminov
Message:

trunk: Merged in qt 4.6.1 sources.

Location:
trunk
Files:
86 edited
9 copied

Legend:

Unmodified
Added
Removed
  • trunk

  • trunk/src/gui/text/qabstractfontengine_p.h

    r2 r561  
    22**
    33** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
    4 ** Contact: Qt Software Information (qt-info@nokia.com)
     4** All rights reserved.
     5** Contact: Nokia Corporation (qt-info@nokia.com)
    56**
    67** This file is part of the QtGui module of the Qt Toolkit.
     
    2122** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    2223**
    23 ** In addition, as a special exception, Nokia gives you certain
    24 ** additional rights. These rights are described in the Nokia Qt LGPL
    25 ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
    26 ** package.
     24** In addition, as a special exception, Nokia gives you certain additional
     25** rights.  These rights are described in the Nokia Qt LGPL Exception
     26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
    2727**
    2828** GNU General Public License Usage
     
    3434** met: http://www.gnu.org/copyleft/gpl.html.
    3535**
    36 ** If you are unsure which license is appropriate for your use, please
    37 ** contact the sales department at qt-sales@nokia.com.
     36** If you have questions regarding the use of this file, please contact
     37** Nokia at qt-info@nokia.com.
    3838** $QT_END_LICENSE$
    3939**
     
    9292    virtual const char *name() const { return "proxy engine"; }
    9393
    94 #if !defined(Q_WS_X11) && !defined(Q_WS_WIN) && !defined(Q_WS_MAC)
     94#if !defined(Q_WS_X11) && !defined(Q_WS_WIN) && !defined(Q_WS_MAC) && !defined(Q_OS_SYMBIAN)
    9595    virtual void draw(QPaintEngine *, qreal, qreal, const QTextItemInt &);
    9696#endif
  • trunk/src/gui/text/qabstracttextdocumentlayout.cpp

    r2 r561  
    22**
    33** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
    4 ** Contact: Qt Software Information (qt-info@nokia.com)
     4** All rights reserved.
     5** Contact: Nokia Corporation (qt-info@nokia.com)
    56**
    67** This file is part of the QtGui module of the Qt Toolkit.
     
    2122** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    2223**
    23 ** In addition, as a special exception, Nokia gives you certain
    24 ** additional rights. These rights are described in the Nokia Qt LGPL
    25 ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
    26 ** package.
     24** In addition, as a special exception, Nokia gives you certain additional
     25** rights.  These rights are described in the Nokia Qt LGPL Exception
     26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
    2727**
    2828** GNU General Public License Usage
     
    3434** met: http://www.gnu.org/copyleft/gpl.html.
    3535**
    36 ** If you are unsure which license is appropriate for your use, please
    37 ** contact the sales department at qt-sales@nokia.com.
     36** If you have questions regarding the use of this file, please contact
     37** Nokia at qt-info@nokia.com.
    3838** $QT_END_LICENSE$
    3939**
     
    5656    class used to implement custom layouts for QTextDocuments.
    5757
    58     \ingroup text
     58    \ingroup richtext-processing
    5959
    6060    The standard layout provided by Qt can handle simple word processing
     
    8080    \brief The QTextObjectInterface class allows drawing of
    8181           custom text objects in \l{QTextDocument}s.
     82    \since 4.5
    8283
    8384    A text object describes the structure of one or more elements in a
  • trunk/src/gui/text/qabstracttextdocumentlayout.h

    r2 r561  
    22**
    33** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
    4 ** Contact: Qt Software Information (qt-info@nokia.com)
     4** All rights reserved.
     5** Contact: Nokia Corporation (qt-info@nokia.com)
    56**
    67** This file is part of the QtGui module of the Qt Toolkit.
     
    2122** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    2223**
    23 ** In addition, as a special exception, Nokia gives you certain
    24 ** additional rights. These rights are described in the Nokia Qt LGPL
    25 ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
    26 ** package.
     24** In addition, as a special exception, Nokia gives you certain additional
     25** rights.  These rights are described in the Nokia Qt LGPL Exception
     26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
    2727**
    2828** GNU General Public License Usage
     
    3434** met: http://www.gnu.org/copyleft/gpl.html.
    3535**
    36 ** If you are unsure which license is appropriate for your use, please
    37 ** contact the sales department at qt-sales@nokia.com.
     36** If you have questions regarding the use of this file, please contact
     37** Nokia at qt-info@nokia.com.
    3838** $QT_END_LICENSE$
    3939**
     
    123123
    124124private:
     125    friend class QTextControl;
    125126    friend class QTextDocument;
    126127    friend class QTextDocumentPrivate;
  • trunk/src/gui/text/qabstracttextdocumentlayout_p.h

    r2 r561  
    22**
    33** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
    4 ** Contact: Qt Software Information (qt-info@nokia.com)
     4** All rights reserved.
     5** Contact: Nokia Corporation (qt-info@nokia.com)
    56**
    67** This file is part of the QtGui module of the Qt Toolkit.
     
    2122** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    2223**
    23 ** In addition, as a special exception, Nokia gives you certain
    24 ** additional rights. These rights are described in the Nokia Qt LGPL
    25 ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
    26 ** package.
     24** In addition, as a special exception, Nokia gives you certain additional
     25** rights.  These rights are described in the Nokia Qt LGPL Exception
     26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
    2727**
    2828** GNU General Public License Usage
     
    3434** met: http://www.gnu.org/copyleft/gpl.html.
    3535**
    36 ** If you are unsure which license is appropriate for your use, please
    37 ** contact the sales department at qt-sales@nokia.com.
     36** If you have questions regarding the use of this file, please contact
     37** Nokia at qt-info@nokia.com.
    3838** $QT_END_LICENSE$
    3939**
  • trunk/src/gui/text/qcssparser.cpp

    r2 r561  
    22**
    33** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
    4 ** Contact: Qt Software Information (qt-info@nokia.com)
     4** All rights reserved.
     5** Contact: Nokia Corporation (qt-info@nokia.com)
    56**
    67** This file is part of the QtGui module of the Qt Toolkit.
     
    2122** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    2223**
    23 ** In addition, as a special exception, Nokia gives you certain
    24 ** additional rights. These rights are described in the Nokia Qt LGPL
    25 ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
    26 ** package.
     24** In addition, as a special exception, Nokia gives you certain additional
     25** rights.  These rights are described in the Nokia Qt LGPL Exception
     26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
    2727**
    2828** GNU General Public License Usage
     
    3434** met: http://www.gnu.org/copyleft/gpl.html.
    3535**
    36 ** If you are unsure which license is appropriate for your use, please
    37 ** contact the sales department at qt-sales@nokia.com.
     36** If you have questions regarding the use of this file, please contact
     37** Nokia at qt-info@nokia.com.
    3838** $QT_END_LICENSE$
    3939**
     
    4949#include <qbrush.h>
    5050#include <qimagereader.h>
     51#include "private/qfunctions_p.h"
    5152
    5253#ifndef QT_NO_CSSPARSER
     
    5758
    5859using namespace QCss;
    59 
    60 const char *Scanner::tokenName(QCss::TokenType t)
    61 {
    62     switch (t) {
    63         case NONE: return "NONE";
    64         case S: return "S";
    65         case CDO: return "CDO";
    66         case CDC: return "CDC";
    67         case INCLUDES: return "INCLUDES";
    68         case DASHMATCH: return "DASHMATCH";
    69         case LBRACE: return "LBRACE";
    70         case PLUS: return "PLUS";
    71         case GREATER: return "GREATER";
    72         case COMMA: return "COMMA";
    73         case STRING: return "STRING";
    74         case INVALID: return "INVALID";
    75         case IDENT: return "IDENT";
    76         case HASH: return "HASH";
    77         case ATKEYWORD_SYM: return "ATKEYWORD_SYM";
    78         case EXCLAMATION_SYM: return "EXCLAMATION_SYM";
    79         case LENGTH: return "LENGTH";
    80         case PERCENTAGE: return "PERCENTAGE";
    81         case NUMBER: return "NUMBER";
    82         case FUNCTION: return "FUNCTION";
    83         case COLON: return "COLON";
    84         case SEMICOLON: return "SEMICOLON";
    85         case RBRACE: return "RBRACE";
    86         case SLASH: return "SLASH";
    87         case MINUS: return "MINUS";
    88         case DOT: return "DOT";
    89         case STAR: return "STAR";
    90         case LBRACKET: return "LBRACKET";
    91         case RBRACKET: return "RBRACKET";
    92         case EQUAL: return "EQUAL";
    93         case LPAREN: return "LPAREN";
    94         case RPAREN: return "RPAREN";
    95         case OR: return "OR";
    96     }
    97     return "";
    98 }
    9960
    10061struct QCssKnownValue
     
    240201    { "link-visited", Value_LinkVisited },
    241202    { "lower-alpha", Value_LowerAlpha },
     203    { "lower-roman", Value_LowerRoman },
    242204    { "lowercase", Value_Lowercase },
    243205    { "medium", Value_Medium },
     
    271233    { "underline", Value_Underline },
    272234    { "upper-alpha", Value_UpperAlpha },
     235    { "upper-roman", Value_UpperRoman },
    273236    { "uppercase", Value_Uppercase },
    274237    { "wave", Value_Wave },
     
    279242};
    280243
     244//Map id to strings as they appears in the 'values' array above
     245static const short indexOfId[NumKnownValues] = { 0, 41, 48, 42, 49, 54, 35, 26, 70, 71, 25, 43, 5, 63, 47,
     246    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,
     247    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,
     248    1, 15, 0, 52, 45, 44 };
     249
    281250QString Value::toString() const
    282251{
    283     static int indexOfId[NumKnownValues - 1];
    284     static bool hasCachedIndexes = false;
    285 
    286252    if (type == KnownIdentifier) {
    287         if (!hasCachedIndexes) {
    288             for (int i = 0; i < NumKnownValues - 1; ++i)
    289                 indexOfId[values[i].id] = i;
    290 
    291             hasCachedIndexes = true;
    292         }
    293 
    294253        return QLatin1String(values[indexOfId[variant.toInt()]].name);
    295254    } else {
     
    383342};
    384343
    385 static bool operator<(const QString &name, const QCssKnownValue &prop)
     344Q_STATIC_GLOBAL_OPERATOR bool operator<(const QString &name, const QCssKnownValue &prop)
    386345{
    387346    return QString::compare(name, QLatin1String(prop.name), Qt::CaseInsensitive) < 0;
    388347}
    389348
    390 static bool operator<(const QCssKnownValue &prop, const QString &name)
     349Q_STATIC_GLOBAL_OPERATOR bool operator<(const QCssKnownValue &prop, const QString &name)
    391350{
    392351    return QString::compare(QLatin1String(prop.name), name, Qt::CaseInsensitive) < 0;
     
    425384        s.chop(2);
    426385
    427     bool ok;
    428     data.number = s.toDouble(&ok);
    429     if (!ok)
    430         data.number = 0;
     386    data.number = s.toDouble();
    431387    return data;
    432388}
     
    754710    for (int i = 0; i < qMin(colorDigits.count(), 7); i += 2) {
    755711        if (colorDigits.at(i).type == Value::Percentage) {
    756             colorDigits[i].variant = colorDigits.at(i).variant.toDouble() * 255. / 100.;
     712            colorDigits[i].variant = colorDigits.at(i).variant.toReal() * (255. / 100.);
    757713            colorDigits[i].type = Value::Number;
    758714        } else if (colorDigits.at(i).type != Value::Number) {
     
    831787            if(cd.type == ColorData::Role)
    832788                dependsOnThePalette = true;
    833             stops.append(QGradientStop(stop.variant.toDouble(), colorFromData(cd, pal)));
     789            stops.append(QGradientStop(stop.variant.toReal(), colorFromData(cd, pal)));
    834790        } else {
    835791            parser.next();
    836792            Value value;
    837             parser.parseTerm(&value);
     793            (void)parser.parseTerm(&value);
    838794            if (attr.compare(QLatin1String("spread"), Qt::CaseInsensitive) == 0) {
    839795                spread = spreads.indexOf(value.variant.toString());
    840796            } else {
    841                 vars[attr] = value.variant.toString().toDouble();
     797                vars[attr] = value.variant.toReal();
    842798            }
    843799        }
    844800        parser.skipSpace();
    845         parser.test(COMMA);
     801        (void)parser.test(COMMA);
    846802    }
    847803
     
    11221078        s.chop(2);
    11231079        value.variant = s;
    1124         if (value.variant.convert(QVariant::Double)) {
    1125             font->setPointSizeF(value.variant.toDouble());
     1080        if (value.variant.convert((QVariant::Type)qMetaTypeId<qreal>())) {
     1081            font->setPointSizeF(value.variant.toReal());
    11261082            valid = true;
    11271083        }
     
    11661122}
    11671123
    1168 static bool setFontFamilyFromValues(const QVector<Value> &values, QFont *font)
     1124/** \internal
     1125 * parse the font family from the values (starting from index \a start)
     1126 * and set it the \a font
     1127 * \returns true if a family was extracted.
     1128 */
     1129static bool setFontFamilyFromValues(const QVector<Value> &values, QFont *font, int start = 0)
    11691130{
    11701131    QString family;
    1171     for (int i = 0; i < values.count(); ++i) {
     1132    bool shouldAddSpace = false;
     1133    for (int i = start; i < values.count(); ++i) {
    11721134        const Value &v = values.at(i);
    1173         if (v.type == Value::TermOperatorComma)
    1174             break;
     1135        if (v.type == Value::TermOperatorComma) {
     1136            family += QLatin1Char(',');
     1137            shouldAddSpace = false;
     1138            continue;
     1139        }
    11751140        const QString str = v.variant.toString();
    11761141        if (str.isEmpty())
    11771142            break;
     1143        if (shouldAddSpace)
     1144            family += QLatin1Char(' ');
    11781145        family += str;
    1179         family += QLatin1Char(' ');
    1180     }
    1181     family = family.simplified();
     1146        shouldAddSpace = true;
     1147    }
    11821148    if (family.isEmpty())
    11831149        return false;
     
    12091175    font->setStyle(QFont::StyleNormal);
    12101176    font->setWeight(QFont::Normal);
    1211     *fontSizeAdjustment = 0;
     1177    *fontSizeAdjustment = -255;
    12121178
    12131179    int i = 0;
     
    12261192
    12271193    if (i < values.count()) {
    1228         QString fam = values.at(i).variant.toString();
    1229         if (!fam.isEmpty())
    1230             font->setFamily(fam);
     1194        setFontFamilyFromValues(values, font, i);
    12311195    }
    12321196}
     
    15081472    if (func.count() != 2 || func.at(0).compare(QLatin1String("rect")) != 0)
    15091473        return QRect();
    1510     QStringList args = func[1].split(QLatin1String(" "), QString::SkipEmptyParts);
     1474    QStringList args = func[1].split(QLatin1Char(' '), QString::SkipEmptyParts);
    15111475    if (args.count() != 4)
    15121476        return QRect();
     
    21532117        QFile file(css);
    21542118        if (file.open(QFile::ReadOnly)) {
    2155             sourcePath = QFileInfo(styleSheet).absolutePath() + QLatin1String("/");
     2119            sourcePath = QFileInfo(styleSheet).absolutePath() + QLatin1Char('/');
    21562120            QTextStream stream(&file);
    21572121            styleSheet = stream.readAll();
     
    21662130    hasEscapeSequences = false;
    21672131    symbols.resize(0);
     2132    symbols.reserve(8);
    21682133    Scanner::scan(Scanner::preprocess(styleSheet, &hasEscapeSequences), &symbols);
    21692134    index = 0;
     
    24992464bool Parser::parsePseudo(Pseudo *pseudo)
    25002465{
    2501     test(COLON);
     2466    (void)test(COLON);
    25022467    pseudo->negated = test(EXCLAMATION_SYM);
    25032468    if (test(IDENT)) {
  • trunk/src/gui/text/qcssparser_p.h

    r2 r561  
    22**
    33** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
    4 ** Contact: Qt Software Information (qt-info@nokia.com)
     4** All rights reserved.
     5** Contact: Nokia Corporation (qt-info@nokia.com)
    56**
    67** This file is part of the QtGui module of the Qt Toolkit.
     
    2122** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    2223**
    23 ** In addition, as a special exception, Nokia gives you certain
    24 ** additional rights. These rights are described in the Nokia Qt LGPL
    25 ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
    26 ** package.
     24** In addition, as a special exception, Nokia gives you certain additional
     25** rights.  These rights are described in the Nokia Qt LGPL Exception
     26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
    2727**
    2828** GNU General Public License Usage
     
    3434** met: http://www.gnu.org/copyleft/gpl.html.
    3535**
    36 ** If you are unsure which license is appropriate for your use, please
    37 ** contact the sales department at qt-sales@nokia.com.
     36** If you have questions regarding the use of this file, please contact
     37** Nokia at qt-info@nokia.com.
    3838** $QT_END_LICENSE$
    3939**
     
    6767
    6868#ifndef QT_NO_CSSPARSER
     69
     70// VxWorks defines NONE as (-1) "for times when NULL won't do"
     71#if defined(Q_OS_VXWORKS) && defined(NONE)
     72#  undef NONE
     73#endif
    6974
    7075QT_BEGIN_NAMESPACE
     
    224229    Value_LowerAlpha,
    225230    Value_UpperAlpha,
     231    Value_LowerRoman,
     232    Value_UpperRoman,
    226233    Value_SmallCaps,
    227234    Value_Uppercase,
     
    362369
    363370struct ColorData {
    364     ColorData() : type(Invalid) {}
    365     ColorData(const QColor &col) : color(col) , type(Color) {}
    366     ColorData(QPalette::ColorRole r) : role(r) , type(Role) {}
     371    ColorData() : role(QPalette::NoRole), type(Invalid) {}
     372    ColorData(const QColor &col) : color(col), role(QPalette::NoRole), type(Color) {}
     373    ColorData(QPalette::ColorRole r) : role(r), type(Role) {}
    367374    QColor color;
    368375    QPalette::ColorRole role;
     
    371378
    372379struct BrushData {
    373     BrushData() : type(Invalid) {}
    374     BrushData(const QBrush &br) : brush(br) , type(Brush) {}
    375     BrushData(QPalette::ColorRole r) : role(r) , type(Role) {}
     380    BrushData() : role(QPalette::NoRole), type(Invalid) {}
     381    BrushData(const QBrush &br) : brush(br), role(QPalette::NoRole), type(Brush) {}
     382    BrushData(QPalette::ColorRole r) : role(r), type(Role) {}
    376383    QBrush brush;
    377384    QPalette::ColorRole role;
     
    404411// 5. Declaration - prop1: value1;
    405412
    406 struct Q_GUI_EXPORT Declaration
     413struct Q_AUTOTEST_EXPORT Declaration
    407414{
    408415    struct DeclarationData : public QSharedData
     
    496503const int NumPseudos = 46;
    497504
    498 struct Q_GUI_EXPORT Pseudo
    499 {
    500     Pseudo() : negated(false) { }
     505struct Pseudo
     506{
     507    Pseudo() : type(0), negated(false) { }
    501508    quint64 type;
    502509    QString name;
     
    505512};
    506513
    507 struct Q_GUI_EXPORT AttributeSelector
     514struct AttributeSelector
    508515{
    509516    enum ValueMatchType {
     
    520527};
    521528
    522 struct Q_GUI_EXPORT BasicSelector
     529struct BasicSelector
    523530{
    524531    inline BasicSelector() : relationToNext(NoRelation) {}
     
    540547};
    541548
    542 struct Q_GUI_EXPORT Selector
     549struct Q_AUTOTEST_EXPORT Selector
    543550{
    544551    QVector<BasicSelector> basicSelectors;
     
    553560struct ImportRule;
    554561
    555 struct Q_GUI_EXPORT ValueExtractor
     562struct Q_AUTOTEST_EXPORT ValueExtractor
    556563{
    557564    ValueExtractor(const QVector<Declaration> &declarations, const QPalette & = QPalette());
     
    587594};
    588595
    589 struct Q_GUI_EXPORT StyleRule
     596struct StyleRule
    590597{
    591598    StyleRule() : order(0) { }
     
    595602};
    596603
    597 struct Q_GUI_EXPORT MediaRule
     604struct MediaRule
    598605{
    599606    QStringList media;
     
    601608};
    602609
    603 struct Q_GUI_EXPORT PageRule
     610struct PageRule
    604611{
    605612    QString selector;
     
    607614};
    608615
    609 struct Q_GUI_EXPORT ImportRule
     616struct ImportRule
    610617{
    611618    QString href;
     
    621628};
    622629
    623 struct Q_GUI_EXPORT StyleSheet
     630struct StyleSheet
    624631{
    625632    StyleSheet() : origin(StyleSheetOrigin_Unspecified), depth(0) { }
     
    720727struct Q_GUI_EXPORT Symbol
    721728{
    722     inline Symbol() : start(0), len(-1) {}
     729    inline Symbol() : token(NONE), start(0), len(-1) {}
    723730    TokenType token;
    724731    QString text;
     
    732739    static QString preprocess(const QString &input, bool *hasEscapeSequences = 0);
    733740    static void scan(const QString &preprocessedInput, QVector<Symbol> *symbols);
    734     static const char *tokenName(TokenType t);
    735741};
    736742
  • trunk/src/gui/text/qcssscanner.cpp

    r2 r561  
    22**
    33** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
    4 ** Contact: Qt Software Information (qt-info@nokia.com)
     4** All rights reserved.
     5** Contact: Nokia Corporation (qt-info@nokia.com)
    56**
    67** This file is part of the QtGui module of the Qt Toolkit.
     
    2122** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    2223**
    23 ** In addition, as a special exception, Nokia gives you certain
    24 ** additional rights. These rights are described in the Nokia Qt LGPL
    25 ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
    26 ** package.
     24** In addition, as a special exception, Nokia gives you certain additional
     25** rights.  These rights are described in the Nokia Qt LGPL Exception
     26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
    2727**
    2828** GNU General Public License Usage
     
    3434** met: http://www.gnu.org/copyleft/gpl.html.
    3535**
    36 ** If you are unsure which license is appropriate for your use, please
    37 ** contact the sales department at qt-sales@nokia.com.
     36** If you have questions regarding the use of this file, please contact
     37** Nokia at qt-info@nokia.com.
    3838** $QT_END_LICENSE$
    3939**
     
    4747
    4848    inline QChar next() {
    49         return (pos < input.length()) ? input.at(pos++).toLower() : QChar();
     49        return (pos < input.length()) ? input.at(pos++) : QChar();
    5050    }
    5151    int handleCommentStart();
     
    7474    int token = -1;
    7575    QChar ch;
    76    
     76
    7777    // initial state
    7878        ch = next();
     
    147147        if (ch.unicode() == 95)
    148148            goto state_24;
    149         if ((ch.unicode() >= 'a' && ch.unicode() <= 'z') || ch.unicode() >= 256)
     149        if ((ch.unicode() >= 'a' && ch.unicode() <= 'z') || (ch.unicode() >= 'A' && ch.unicode() <= 'Z') || ch.unicode() >= 256)
    150150            goto state_24;
    151151        if (ch.unicode() == 123)
     
    197197        if (ch.unicode() >= 93 && ch.unicode() <= 96)
    198198            goto state_30;
    199         if ((ch.unicode() >= 'a' && ch.unicode() <= 'z') || ch.unicode() >= 256)
     199        if ((ch.unicode() >= 'a' && ch.unicode() <= 'z') || (ch.unicode() >= 'A' && ch.unicode() <= 'Z') || ch.unicode() >= 256)
    200200            goto state_30;
    201201        if (ch.unicode() >= 123)
     
    212212        if (ch.unicode() == 95)
    213213            goto state_33;
    214         if ((ch.unicode() >= 'a' && ch.unicode() <= 'z') || ch.unicode() >= 256)
     214        if ((ch.unicode() >= 'a' && ch.unicode() <= 'z') || (ch.unicode() >= 'A' && ch.unicode() <= 'Z') || ch.unicode() >= 256)
    215215            goto state_33;
    216216        goto out;
     
    233233        if (ch.unicode() >= 93 && ch.unicode() <= 96)
    234234            goto state_35;
    235         if ((ch.unicode() >= 'a' && ch.unicode() <= 'z') || ch.unicode() >= 256)
     235        if ((ch.unicode() >= 'a' && ch.unicode() <= 'z') || (ch.unicode() >= 'A' && ch.unicode() <= 'Z') || ch.unicode() >= 256)
    236236            goto state_35;
    237237        if (ch.unicode() >= 123)
     
    256256        if (ch.unicode() == 95)
    257257            goto state_24;
    258         if ((ch.unicode() >= 'a' && ch.unicode() <= 'z') || ch.unicode() >= 256)
     258        if ((ch.unicode() >= 'a' && ch.unicode() <= 'z') || (ch.unicode() >= 'A' && ch.unicode() <= 'Z') || ch.unicode() >= 256)
    259259            goto state_24;
    260260        goto out;
     
    291291        if (ch.unicode() == 95)
    292292            goto state_46;
    293         if ((ch.unicode() >= 'a' && ch.unicode() <= 'z') || ch.unicode() >= 256)
     293        if ((ch.unicode() >= 'a' && ch.unicode() <= 'z') || (ch.unicode() >= 'A' && ch.unicode() <= 'Z') || ch.unicode() >= 256)
    294294            goto state_46;
    295295        goto out;
     
    311311        if (ch.unicode() == 95)
    312312            goto state_50;
    313         if ((ch.unicode() >= 'a' && ch.unicode() <= 'z') || ch.unicode() >= 256)
     313        if ((ch.unicode() >= 'a' && ch.unicode() <= 'z') || (ch.unicode() >= 'A' && ch.unicode() <= 'Z') || ch.unicode() >= 256)
    314314            goto state_50;
    315315        goto out;
     
    341341        if (ch.unicode() == 95)
    342342            goto state_53;
    343         if ((ch.unicode() >= 'a' && ch.unicode() <= 'z') || ch.unicode() >= 256)
     343        if ((ch.unicode() >= 'a' && ch.unicode() <= 'z') || (ch.unicode() >= 'A' && ch.unicode() <= 'Z') || ch.unicode() >= 256)
    344344            goto state_53;
    345345        goto out;
     
    401401        if (ch.unicode() >= 93 && ch.unicode() <= 96)
    402402            goto state_30;
    403         if ((ch.unicode() >= 'a' && ch.unicode() <= 'z') || ch.unicode() >= 256)
     403        if ((ch.unicode() >= 'a' && ch.unicode() <= 'z') || (ch.unicode() >= 'A' && ch.unicode() <= 'Z') || ch.unicode() >= 256)
    404404            goto state_30;
    405405        if (ch.unicode() >= 123)
     
    441441        if (ch.unicode() == 95)
    442442            goto state_61;
    443         if ((ch.unicode() >= 'a' && ch.unicode() <= 'z') || ch.unicode() >= 256)
     443        if ((ch.unicode() >= 'a' && ch.unicode() <= 'z') || (ch.unicode() >= 'A' && ch.unicode() <= 'Z') || ch.unicode() >= 256)
    444444            goto state_61;
    445445        goto out;
     
    475475        if (ch.unicode() >= 93 && ch.unicode() <= 96)
    476476            goto state_35;
    477         if ((ch.unicode() >= 'a' && ch.unicode() <= 'z') || ch.unicode() >= 256)
     477        if ((ch.unicode() >= 'a' && ch.unicode() <= 'z') || (ch.unicode() >= 'A' && ch.unicode() <= 'Z') || ch.unicode() >= 256)
    478478            goto state_35;
    479479        if (ch.unicode() >= 123)
     
    524524        if (ch.unicode() == 95)
    525525            goto state_46;
    526         if ((ch.unicode() >= 'a' && ch.unicode() <= 'z') || ch.unicode() >= 256)
     526        if ((ch.unicode() >= 'a' && ch.unicode() <= 'z') || (ch.unicode() >= 'A' && ch.unicode() <= 'Z') || ch.unicode() >= 256)
    527527            goto state_46;
    528528        goto out;
     
    537537        if (ch.unicode() == 95)
    538538            goto state_46;
    539         if ((ch.unicode() >= 'a' && ch.unicode() <= 'z') || ch.unicode() >= 256)
     539        if ((ch.unicode() >= 'a' && ch.unicode() <= 'z') || (ch.unicode() >= 'A' && ch.unicode() <= 'Z') || ch.unicode() >= 256)
    540540            goto state_46;
    541541        goto out;
     
    561561        if (ch.unicode() == 95)
    562562            goto state_46;
    563         if ((ch.unicode() >= 'a' && ch.unicode() <= 'z') || ch.unicode() >= 256)
     563        if ((ch.unicode() >= 'a' && ch.unicode() <= 'z') || (ch.unicode() >= 'A' && ch.unicode() <= 'Z') || ch.unicode() >= 256)
    564564            goto state_46;
    565565        goto out;
     
    589589        if (ch.unicode() == 95)
    590590            goto state_71;
    591         if ((ch.unicode() >= 'a' && ch.unicode() <= 'z') || ch.unicode() >= 256)
     591        if ((ch.unicode() >= 'a' && ch.unicode() <= 'z') || (ch.unicode() >= 'A' && ch.unicode() <= 'Z') || ch.unicode() >= 256)
    592592            goto state_71;
    593593        goto out;
     
    603603        if (ch.unicode() == 95)
    604604            goto state_50;
    605         if ((ch.unicode() >= 'a' && ch.unicode() <= 'z') || ch.unicode() >= 256)
     605        if ((ch.unicode() >= 'a' && ch.unicode() <= 'z') || (ch.unicode() >= 'A' && ch.unicode() <= 'Z') || ch.unicode() >= 256)
    606606            goto state_50;
    607607        goto out;
     
    631631        if (ch.unicode() == 95)
    632632            goto state_75;
    633         if ((ch.unicode() >= 'a' && ch.unicode() <= 'z') || ch.unicode() >= 256)
     633        if ((ch.unicode() >= 'a' && ch.unicode() <= 'z') || (ch.unicode() >= 'A' && ch.unicode() <= 'Z') || ch.unicode() >= 256)
    634634            goto state_75;
    635635        goto out;
     
    648648        if (ch.unicode() == 95)
    649649            goto state_53;
    650         if ((ch.unicode() >= 'a' && ch.unicode() <= 'z') || ch.unicode() >= 256)
     650        if ((ch.unicode() >= 'a' && ch.unicode() <= 'z') || (ch.unicode() >= 'A' && ch.unicode() <= 'Z') || ch.unicode() >= 256)
    651651            goto state_53;
    652652        goto out;
     
    669669        if (ch.unicode() == 95)
    670670            goto state_53;
    671         if ((ch.unicode() >= 'a' && ch.unicode() <= 'z') || ch.unicode() >= 256)
     671        if ((ch.unicode() >= 'a' && ch.unicode() <= 'z') || (ch.unicode() >= 'A' && ch.unicode() <= 'Z') || ch.unicode() >= 256)
    672672            goto state_53;
    673673        goto out;
     
    703703        if (ch.unicode() >= 93 && ch.unicode() <= 96)
    704704            goto state_30;
    705         if ((ch.unicode() >= 'a' && ch.unicode() <= 'z') || ch.unicode() >= 256)
     705        if ((ch.unicode() >= 'a' && ch.unicode() <= 'z') || (ch.unicode() >= 'A' && ch.unicode() <= 'Z') || ch.unicode() >= 256)
    706706            goto state_30;
    707707        if (ch.unicode() >= 123)
     
    726726        if (ch.unicode() >= 93 && ch.unicode() <= 96)
    727727            goto state_30;
    728         if ((ch.unicode() >= 'a' && ch.unicode() <= 'z') || ch.unicode() >= 256)
     728        if ((ch.unicode() >= 'a' && ch.unicode() <= 'z') || (ch.unicode() >= 'A' && ch.unicode() <= 'Z') || ch.unicode() >= 256)
    729729            goto state_30;
    730730        if (ch.unicode() >= 123)
     
    749749        if (ch.unicode() >= 93 && ch.unicode() <= 96)
    750750            goto state_30;
    751         if ((ch.unicode() >= 'a' && ch.unicode() <= 'z') || ch.unicode() >= 256)
     751        if ((ch.unicode() >= 'a' && ch.unicode() <= 'z') || (ch.unicode() >= 'A' && ch.unicode() <= 'Z') || ch.unicode() >= 256)
    752752            goto state_30;
    753753        if (ch.unicode() >= 123)
     
    774774        if (ch.unicode() >= 93 && ch.unicode() <= 96)
    775775            goto state_30;
    776         if ((ch.unicode() >= 'a' && ch.unicode() <= 'z') || ch.unicode() >= 256)
     776        if ((ch.unicode() >= 'a' && ch.unicode() <= 'z') || (ch.unicode() >= 'A' && ch.unicode() <= 'Z') || ch.unicode() >= 256)
    777777            goto state_30;
    778778        if (ch.unicode() >= 123)
     
    791791        if (ch.unicode() == 95)
    792792            goto state_61;
    793         if ((ch.unicode() >= 'a' && ch.unicode() <= 'z') || ch.unicode() >= 256)
     793        if ((ch.unicode() >= 'a' && ch.unicode() <= 'z') || (ch.unicode() >= 'A' && ch.unicode() <= 'Z') || ch.unicode() >= 256)
    794794            goto state_61;
    795795        goto out;
     
    819819        if (ch.unicode() == 95)
    820820            goto state_61;
    821         if ((ch.unicode() >= 'a' && ch.unicode() <= 'z') || ch.unicode() >= 256)
     821        if ((ch.unicode() >= 'a' && ch.unicode() <= 'z') || (ch.unicode() >= 'A' && ch.unicode() <= 'Z') || ch.unicode() >= 256)
    822822            goto state_61;
    823823        goto out;
     
    840840        if (ch.unicode() >= 93 && ch.unicode() <= 96)
    841841            goto state_35;
    842         if ((ch.unicode() >= 'a' && ch.unicode() <= 'z') || ch.unicode() >= 256)
     842        if ((ch.unicode() >= 'a' && ch.unicode() <= 'z') || (ch.unicode() >= 'A' && ch.unicode() <= 'Z') || ch.unicode() >= 256)
    843843            goto state_35;
    844844        if (ch.unicode() >= 123)
     
    863863        if (ch.unicode() >= 93 && ch.unicode() <= 96)
    864864            goto state_35;
    865         if ((ch.unicode() >= 'a' && ch.unicode() <= 'z') || ch.unicode() >= 256)
     865        if ((ch.unicode() >= 'a' && ch.unicode() <= 'z') || (ch.unicode() >= 'A' && ch.unicode() <= 'Z') || ch.unicode() >= 256)
    866866            goto state_35;
    867867        if (ch.unicode() >= 123)
     
    886886        if (ch.unicode() >= 93 && ch.unicode() <= 96)
    887887            goto state_35;
    888         if ((ch.unicode() >= 'a' && ch.unicode() <= 'z') || ch.unicode() >= 256)
     888        if ((ch.unicode() >= 'a' && ch.unicode() <= 'z') || (ch.unicode() >= 'A' && ch.unicode() <= 'Z') || ch.unicode() >= 256)
    889889            goto state_35;
    890890        if (ch.unicode() >= 123)
     
    911911        if (ch.unicode() >= 93 && ch.unicode() <= 96)
    912912            goto state_35;
    913         if ((ch.unicode() >= 'a' && ch.unicode() <= 'z') || ch.unicode() >= 256)
     913        if ((ch.unicode() >= 'a' && ch.unicode() <= 'z') || (ch.unicode() >= 'A' && ch.unicode() <= 'Z') || ch.unicode() >= 256)
    914914            goto state_35;
    915915        if (ch.unicode() >= 123)
     
    930930        if (ch.unicode() == 95)
    931931            goto state_46;
    932         if ((ch.unicode() >= 'a' && ch.unicode() <= 'z') || ch.unicode() >= 256)
     932        if ((ch.unicode() >= 'a' && ch.unicode() <= 'z') || (ch.unicode() >= 'A' && ch.unicode() <= 'Z') || ch.unicode() >= 256)
    933933            goto state_46;
    934934        goto out;
     
    945945        if (ch.unicode() == 95)
    946946            goto state_71;
    947         if ((ch.unicode() >= 'a' && ch.unicode() <= 'z') || ch.unicode() >= 256)
     947        if ((ch.unicode() >= 'a' && ch.unicode() <= 'z') || (ch.unicode() >= 'A' && ch.unicode() <= 'Z') || ch.unicode() >= 256)
    948948            goto state_71;
    949949        goto out;
     
    960960        if (ch.unicode() == 95)
    961961            goto state_71;
    962         if ((ch.unicode() >= 'a' && ch.unicode() <= 'z') || ch.unicode() >= 256)
     962        if ((ch.unicode() >= 'a' && ch.unicode() <= 'z') || (ch.unicode() >= 'A' && ch.unicode() <= 'Z') || ch.unicode() >= 256)
    963963            goto state_71;
    964964        goto out;
     
    995995        if (ch.unicode() == 95)
    996996            goto state_75;
    997         if ((ch.unicode() >= 'a' && ch.unicode() <= 'z') || ch.unicode() >= 256)
     997        if ((ch.unicode() >= 'a' && ch.unicode() <= 'z') || (ch.unicode() >= 'A' && ch.unicode() <= 'Z') || ch.unicode() >= 256)
    998998            goto state_75;
    999999        goto out;
     
    10101010        if (ch.unicode() == 95)
    10111011            goto state_75;
    1012         if ((ch.unicode() >= 'a' && ch.unicode() <= 'z') || ch.unicode() >= 256)
     1012        if ((ch.unicode() >= 'a' && ch.unicode() <= 'z') || (ch.unicode() >= 'A' && ch.unicode() <= 'Z') || ch.unicode() >= 256)
    10131013            goto state_75;
    10141014        goto out;
     
    10401040        if (ch.unicode() == 95)
    10411041            goto state_53;
    1042         if ((ch.unicode() >= 'a' && ch.unicode() <= 'z') || ch.unicode() >= 256)
     1042        if ((ch.unicode() >= 'a' && ch.unicode() <= 'z') || (ch.unicode() >= 'A' && ch.unicode() <= 'Z') || ch.unicode() >= 256)
    10431043            goto state_53;
    10441044        goto out;
     
    10611061        if (ch.unicode() >= 93 && ch.unicode() <= 96)
    10621062            goto state_30;
    1063         if ((ch.unicode() >= 'a' && ch.unicode() <= 'z') || ch.unicode() >= 256)
     1063        if ((ch.unicode() >= 'a' && ch.unicode() <= 'z') || (ch.unicode() >= 'A' && ch.unicode() <= 'Z') || ch.unicode() >= 256)
    10641064            goto state_30;
    10651065        if (ch.unicode() >= 123)
     
    10781078        if (ch.unicode() == 95)
    10791079            goto state_61;
    1080         if ((ch.unicode() >= 'a' && ch.unicode() <= 'z') || ch.unicode() >= 256)
     1080        if ((ch.unicode() >= 'a' && ch.unicode() <= 'z') || (ch.unicode() >= 'A' && ch.unicode() <= 'Z') || ch.unicode() >= 256)
    10811081            goto state_61;
    10821082        goto out;
     
    10991099        if (ch.unicode() >= 93 && ch.unicode() <= 96)
    11001100            goto state_35;
    1101         if ((ch.unicode() >= 'a' && ch.unicode() <= 'z') || ch.unicode() >= 256)
     1101        if ((ch.unicode() >= 'a' && ch.unicode() <= 'z') || (ch.unicode() >= 'A' && ch.unicode() <= 'Z') || ch.unicode() >= 256)
    11021102            goto state_35;
    11031103        if (ch.unicode() >= 123)
     
    11161116        if (ch.unicode() == 95)
    11171117            goto state_71;
    1118         if ((ch.unicode() >= 'a' && ch.unicode() <= 'z') || ch.unicode() >= 256)
     1118        if ((ch.unicode() >= 'a' && ch.unicode() <= 'z') || (ch.unicode() >= 'A' && ch.unicode() <= 'Z') || ch.unicode() >= 256)
    11191119            goto state_71;
    11201120        goto out;
     
    11311131        if (ch.unicode() == 95)
    11321132            goto state_75;
    1133         if ((ch.unicode() >= 'a' && ch.unicode() <= 'z') || ch.unicode() >= 256)
     1133        if ((ch.unicode() >= 'a' && ch.unicode() <= 'z') || (ch.unicode() >= 'A' && ch.unicode() <= 'Z') || ch.unicode() >= 256)
    11341134            goto state_75;
    11351135        goto out;
    11361136    found:
    11371137    lastAcceptingPos = pos;
    1138    
     1138
    11391139    out:
    11401140    if (lastAcceptingPos != -1) {
  • trunk/src/gui/text/qfont.cpp

    r124 r561  
    22**
    33** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
    4 ** Contact: Qt Software Information (qt-info@nokia.com)
     4** All rights reserved.
     5** Contact: Nokia Corporation (qt-info@nokia.com)
    56**
    67** This file is part of the QtGui module of the Qt Toolkit.
     
    2122** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    2223**
    23 ** In addition, as a special exception, Nokia gives you certain
    24 ** additional rights. These rights are described in the Nokia Qt LGPL
    25 ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
    26 ** package.
     24** In addition, as a special exception, Nokia gives you certain additional
     25** rights.  These rights are described in the Nokia Qt LGPL Exception
     26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
    2727**
    2828** GNU General Public License Usage
     
    3434** met: http://www.gnu.org/copyleft/gpl.html.
    3535**
    36 ** If you are unsure which license is appropriate for your use, please
    37 ** contact the sales department at qt-sales@nokia.com.
     36** If you have questions regarding the use of this file, please contact
     37** Nokia at qt-info@nokia.com.
    3838** $QT_END_LICENSE$
    3939**
     
    7676#include "qfontengine_qpf_p.h"
    7777#endif
     78#endif
     79#ifdef Q_OS_SYMBIAN
     80#include "qt_s60_p.h"
    7881#endif
    7982
     
    180183        screen = subScreens.at(0);
    181184    dpi = qRound(screen->width() / (screen->physicalWidth() / qreal(25.4)));
     185#elif defined(Q_OS_SYMBIAN)
     186    dpi = S60->defaultDpiX;
    182187#endif // Q_WS_X11
    183188
     
    212217        screen = subScreens.at(0);
    213218    dpi = qRound(screen->height() / (screen->physicalHeight() / qreal(25.4)));
     219#elif defined(Q_OS_SYMBIAN)
     220    dpi = S60->defaultDpiY;
    214221#endif // Q_WS_X11
    215222
     
    227234      capital(0), letterSpacingIsAbsolute(false), scFont(0)
    228235{
    229     ref = 1;
    230236#ifdef Q_WS_X11
    231237    if (QX11Info::display())
     
    247253      scFont(other.scFont)
    248254{
    249     ref = 1;
    250255#ifdef Q_WS_WIN
    251256    hdc = other.hdc;
     
    324329    else
    325330        font.setPixelSize((font.pixelSize() * 7 + 5) / 10);
    326     scFont = font.d;
     331    scFont = font.d.data();
    327332    if (scFont != this)
    328333        scFont->ref.ref();
     
    425430    \brief The QFont class specifies a font used for drawing text.
    426431
    427     \ingroup multimedia
     432    \ingroup painting
    428433    \ingroup appearance
    429434    \ingroup shared
    430     \ingroup text
    431     \mainclass
     435    \ingroup richtext-processing
     436
    432437
    433438    When you create a QFont object you specify various attributes that
     
    735740        d->screen = screen;
    736741    } else {
    737         d = font.d;
    738         d->ref.ref();
     742        d = font.d.data();
    739743    }
    740744#ifdef Q_WS_WIN
     
    748752*/
    749753QFont::QFont(QFontPrivate *data)
    750     : resolve_mask(QFont::AllPropertiesResolved)
    751 {
    752     d = data;
    753     d->ref.ref();
     754    : d(data), resolve_mask(QFont::AllPropertiesResolved)
     755{
    754756}
    755757
     
    763765            d->engineData->ref.deref();
    764766        d->engineData = 0;
    765         if (d->scFont && d->scFont != d)
     767        if (d->scFont && d->scFont != d.data())
    766768            d->scFont->ref.deref();
    767769        d->scFont = 0;
     
    769771    }
    770772
    771     qAtomicDetach(d);
     773    d.detach();
    772774}
    773775
     
    778780*/
    779781QFont::QFont()
    780     :d(QApplication::font().d), resolve_mask(0)
    781 {
    782     d->ref.ref();
     782    : d(QApplication::font().d.data()), resolve_mask(0)
     783{
    783784}
    784785
     
    787788    pointSize, \a weight and \a italic settings.
    788789
    789     If \a pointSize is <= 0, it is set to 12.
     790    If \a pointSize is zero or negative, the point size of the font
     791    is set to a system-dependent default value. Generally, this is
     792    12 points, except on Symbian where it is 7 points.
    790793
    791794    The \a family name may optionally also include a foundry name,
     
    800803*/
    801804QFont::QFont(const QString &family, int pointSize, int weight, bool italic)
    802     :d(new QFontPrivate)
    803 {
    804     resolve_mask = QFont::FamilyResolved;
    805 
     805    : d(new QFontPrivate()), resolve_mask(QFont::FamilyResolved)
     806{
    806807    if (pointSize <= 0) {
     808#ifdef Q_OS_SYMBIAN
     809        pointSize = 7;
     810#else
    807811        pointSize = 12;
     812#endif
    808813    } else {
    809814        resolve_mask |= QFont::SizeResolved;
     
    827832*/
    828833QFont::QFont(const QFont &font)
    829 {
    830     d = font.d;
    831     d->ref.ref();
    832     resolve_mask = font.resolve_mask;
     834    : d(font.d.data()), resolve_mask(font.resolve_mask)
     835{
    833836}
    834837
     
    838841QFont::~QFont()
    839842{
    840     if (!d->ref.deref())
    841         delete d;
    842843}
    843844
     
    847848QFont &QFont::operator=(const QFont &font)
    848849{
    849     qAtomicAssign(d, font.d);
     850    d = font.d.data();
    850851    resolve_mask = font.resolve_mask;
    851852    return *this;
     
    907908void QFont::setPointSize(int pointSize)
    908909{
    909     Q_ASSERT_X (pointSize > 0, "QFont::setPointSize", "point size must be greater than 0");
     910    if (pointSize <= 0) {
     911        qWarning("QFont::setPointSize: Point size <= 0 (%d), must be greater than 0", pointSize);
     912        return;
     913    }
    910914
    911915    detach();
     
    926930void QFont::setPointSizeF(qreal pointSize)
    927931{
    928     Q_ASSERT_X(pointSize > 0.0, "QFont::setPointSizeF", "point size must be greater than 0");
     932    if (pointSize <= 0) {
     933        qWarning("QFont::setPointSizeF: Point size <= 0 (%f), must be greater than 0", pointSize);
     934        return;
     935    }
    929936
    930937    detach();
     
    16231630                && f.d->overline  == d->overline
    16241631                && f.d->strikeOut == d->strikeOut
    1625                 && f.d->kerning == d->kerning));
     1632                && f.d->kerning == d->kerning
     1633                && f.d->capital == d->capital));
    16261634}
    16271635
     
    16551663    if (r1.addStyle != r2.addStyle) return r1.addStyle < r2.addStyle;
    16561664#endif // Q_WS_X11
     1665    if (f.d->capital != d->capital) return f.d->capital < d->capital;
    16571666
    16581667    int f1attrs = (f.d->underline << 3) + (f.d->overline << 2) + (f.d->strikeOut<<1) + f.d->kerning;
     
    17241733    QFont font(*this);
    17251734    font.detach();
    1726     font.d->resolve(resolve_mask, other.d);
     1735    font.d->resolve(resolve_mask, other.d.data());
    17271736
    17281737    return font;
     
    17881797{
    17891798    // default substitutions
    1790     static const char *initTbl[] = {
     1799    static const char * const initTbl[] = {
    17911800
    17921801#if defined(Q_WS_X11)
     
    18201829}
    18211830
    1822 
    18231831/*!
    18241832    Returns the first family name to be used whenever \a familyName is
     
    19071915    }
    19081916}
     1917
     1918/*! \fn void QFont::initialize()
     1919  \internal
     1920
     1921  Internal function that initializes the font system.  The font cache
     1922  and font dict do not alloc the keys. The key is a QString which is
     1923  shared between QFontPrivate and QXFontName.
     1924*/
     1925
     1926/*! \fn void QFont::cleanup()
     1927  \internal
     1928
     1929  Internal function that cleans up the font system.
     1930*/
    19091931
    19101932// ### mark: should be called removeSubstitutions()
     
    21632185    s << (quint8) 0
    21642186      << (quint8) font.d->request.weight
    2165       << get_font_bits(s.version(), font.d);
     2187      << get_font_bits(s.version(), font.d.data());
    21662188    if (s.version() >= QDataStream::Qt_4_3)
    21672189        s << (quint16)font.d->request.stretch;
    21682190    if (s.version() >= QDataStream::Qt_4_4)
    2169         s << get_extended_font_bits(font.d);
     2191        s << get_extended_font_bits(font.d.data());
    21702192    if (s.version() >= QDataStream::Qt_4_5) {
    21712193        s << font.d->letterSpacing.value();
     
    21862208QDataStream &operator>>(QDataStream &s, QFont &font)
    21872209{
    2188     if (!font.d->ref.deref())
    2189         delete font.d;
    2190 
    21912210    font.d = new QFontPrivate;
    21922211    font.resolve_mask = QFont::AllPropertiesResolved;
     
    22302249    font.d->request.weight = weight;
    22312250
    2232     set_font_bits(s.version(), bits, font.d);
     2251    set_font_bits(s.version(), bits, font.d.data());
    22332252
    22342253    if (s.version() >= QDataStream::Qt_4_3) {
     
    22412260        quint8 extendedBits;
    22422261        s >> extendedBits;
    2243         set_extended_font_bits(extendedBits, font.d);
     2262        set_extended_font_bits(extendedBits, font.d.data());
    22442263    }
    22452264    if (s.version() >= QDataStream::Qt_4_5) {
     
    22672286    \brief The QFontInfo class provides general information about fonts.
    22682287
    2269     \ingroup multimedia
     2288    \ingroup appearance
    22702289    \ingroup shared
    2271     \ingroup text
    22722290
    22732291    The QFontInfo class provides the same access functions as QFont,
     
    23232341*/
    23242342QFontInfo::QFontInfo(const QFont &font)
    2325     : d(font.d)
    2326 { d->ref.ref(); }
     2343    : d(font.d.data())
     2344{
     2345}
    23272346
    23282347/*!
     
    23302349*/
    23312350QFontInfo::QFontInfo(const QFontInfo &fi)
    2332     : d(fi.d)
    2333 { d->ref.ref(); }
     2351    : d(fi.d.data())
     2352{
     2353}
    23342354
    23352355/*!
     
    23382358QFontInfo::~QFontInfo()
    23392359{
    2340     if (!d->ref.deref())
    2341         delete d;
    23422360}
    23432361
     
    23472365QFontInfo &QFontInfo::operator=(const QFontInfo &fi)
    23482366{
    2349     qAtomicAssign(d, fi.d);
     2367    d = fi.d.data();
    23502368    return *this;
    23512369}
     
    25962614void QFontCache::cleanup()
    25972615{
    2598     theFontCache()->setLocalData(0);
     2616    QThreadStorage<QFontCache *> *cache = 0;
     2617    QT_TRY {
     2618        cache = theFontCache();
     2619    } QT_CATCH (const std::bad_alloc &) {
     2620        // no cache - just ignore
     2621    }
     2622    if (cache && cache->hasLocalData())
     2623        cache->setLocalData(0);
    25992624}
    26002625#endif // QT_NO_THREAD
     
    26092634{
    26102635    {
    2611         EngineDataCache::Iterator it = engineDataCache.begin(),
    2612                                  end = engineDataCache.end();
     2636        EngineDataCache::ConstIterator it = engineDataCache.constBegin(),
     2637                                 end = engineDataCache.constEnd();
    26132638        while (it != end) {
    26142639            if (it.value()->ref == 0)
     
    26202645        }
    26212646    }
    2622     EngineCache::Iterator it = engineCache.begin(),
    2623                          end = engineCache.end();
     2647    EngineCache::ConstIterator it = engineCache.constBegin(),
     2648                         end = engineCache.constEnd();
    26242649    while (it != end) {
    26252650        if (--it.value().data->cache_count == 0) {
    26262651            if (it.value().data->ref == 0) {
    2627                 FC_DEBUG("QFontCache::~QFontCache: deleting engine %p key=(%d / %g %d %d %d %d)",
     2652                FC_DEBUG("QFontCache::~QFontCache: deleting engine %p key=(%d / %g %g %d %d %d)",
    26282653                         it.value().data, it.key().script, it.key().def.pointSize,
    26292654                         it.key().def.pixelSize, it.key().def.weight, it.key().def.style,
  • trunk/src/gui/text/qfont.h

    r2 r561  
    22**
    33** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
    4 ** Contact: Qt Software Information (qt-info@nokia.com)
     4** All rights reserved.
     5** Contact: Nokia Corporation (qt-info@nokia.com)
    56**
    67** This file is part of the QtGui module of the Qt Toolkit.
     
    2122** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    2223**
    23 ** In addition, as a special exception, Nokia gives you certain
    24 ** additional rights. These rights are described in the Nokia Qt LGPL
    25 ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
    26 ** package.
     24** In addition, as a special exception, Nokia gives you certain additional
     25** rights.  These rights are described in the Nokia Qt LGPL Exception
     26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
    2727**
    2828** GNU General Public License Usage
     
    3434** met: http://www.gnu.org/copyleft/gpl.html.
    3535**
    36 ** If you are unsure which license is appropriate for your use, please
    37 ** contact the sales department at qt-sales@nokia.com.
     36** If you have questions regarding the use of this file, please contact
     37** Nokia at qt-info@nokia.com.
    3838** $QT_END_LICENSE$
    3939**
     
    4545#include <QtGui/qwindowdefs.h>
    4646#include <QtCore/qstring.h>
     47#include <QtCore/qsharedpointer.h>
    4748
    4849#if defined(Q_WS_X11) || defined(Q_WS_QWS)
     
    307308    friend class QTextItemInt;
    308309    friend class QPicturePaintEngine;
     310    friend class QPainterReplayer;
     311    friend class QPaintBufferEngine;
     312    friend class QCommandLinkButtonPrivate;
    309313
    310314#ifndef QT_NO_DATASTREAM
     
    313317#endif
    314318
    315     QFontPrivate *d;
     319    QExplicitlySharedDataPointer<QFontPrivate> d;
    316320    uint resolve_mask;
    317321};
  • trunk/src/gui/text/qfont_mac.cpp

    r2 r561  
    22**
    33** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
    4 ** Contact: Qt Software Information (qt-info@nokia.com)
     4** All rights reserved.
     5** Contact: Nokia Corporation (qt-info@nokia.com)
    56**
    67** This file is part of the QtGui module of the Qt Toolkit.
     
    2122** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    2223**
    23 ** In addition, as a special exception, Nokia gives you certain
    24 ** additional rights. These rights are described in the Nokia Qt LGPL
    25 ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
    26 ** package.
     24** In addition, as a special exception, Nokia gives you certain additional
     25** rights.  These rights are described in the Nokia Qt LGPL Exception
     26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
    2727**
    2828** GNU General Public License Usage
     
    3434** met: http://www.gnu.org/copyleft/gpl.html.
    3535**
    36 ** If you are unsure which license is appropriate for your use, please
    37 ** contact the sales department at qt-sales@nokia.com.
     36** If you have questions regarding the use of this file, please contact
     37** Nokia at qt-info@nokia.com.
    3838** $QT_END_LICENSE$
    3939**
  • trunk/src/gui/text/qfont_p.h

    r226 r561  
    22**
    33** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
    4 ** Contact: Qt Software Information (qt-info@nokia.com)
     4** All rights reserved.
     5** Contact: Nokia Corporation (qt-info@nokia.com)
    56**
    67** This file is part of the QtGui module of the Qt Toolkit.
     
    2122** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    2223**
    23 ** In addition, as a special exception, Nokia gives you certain
    24 ** additional rights. These rights are described in the Nokia Qt LGPL
    25 ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
    26 ** package.
     24** In addition, as a special exception, Nokia gives you certain additional
     25** rights.  These rights are described in the Nokia Qt LGPL Exception
     26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
    2727**
    2828** GNU General Public License Usage
     
    3434** met: http://www.gnu.org/copyleft/gpl.html.
    3535**
    36 ** If you are unsure which license is appropriate for your use, please
    37 ** contact the sales department at qt-sales@nokia.com.
     36** If you have questions regarding the use of this file, please contact
     37** Nokia at qt-info@nokia.com.
    3838** $QT_END_LICENSE$
    3939**
     
    8787
    8888    qreal pointSize;
    89     int pixelSize;
     89    qreal pixelSize;
    9090
    9191    uint styleStrategy : 16;
  • trunk/src/gui/text/qfont_win.cpp

    r2 r561  
    22**
    33** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
    4 ** Contact: Qt Software Information (qt-info@nokia.com)
     4** All rights reserved.
     5** Contact: Nokia Corporation (qt-info@nokia.com)
    56**
    67** This file is part of the QtGui module of the Qt Toolkit.
     
    2122** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    2223**
    23 ** In addition, as a special exception, Nokia gives you certain
    24 ** additional rights. These rights are described in the Nokia Qt LGPL
    25 ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
    26 ** package.
     24** In addition, as a special exception, Nokia gives you certain additional
     25** rights.  These rights are described in the Nokia Qt LGPL Exception
     26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
    2727**
    2828** GNU General Public License Usage
     
    3434** met: http://www.gnu.org/copyleft/gpl.html.
    3535**
    36 ** If you are unsure which license is appropriate for your use, please
    37 ** contact the sales department at qt-sales@nokia.com.
     36** If you have questions regarding the use of this file, please contact
     37** Nokia at qt-info@nokia.com.
    3838** $QT_END_LICENSE$
    3939**
    4040****************************************************************************/
    41 
    42 // the miscrosoft platform SDK says that the Unicode versions of
    43 // TextOut and GetTextExtentsPoint32 are supported on all platforms, so we use them
    44 // exclusively to simplify code, save a lot of conversions into the local encoding
    45 // and have generally better unicode support :)
    4641
    4742#include "qfont.h"
     
    6863QFont qt_LOGFONTtoQFont(LOGFONT& lf, bool /*scale*/)
    6964{
    70     QString family = QT_WA_INLINE(QString::fromUtf16((ushort*)lf.lfFaceName),
    71                                    QString::fromLocal8Bit((char*)lf.lfFaceName));
     65    QString family = QString::fromWCharArray(lf.lfFaceName);
    7266    QFont qf(family);
    7367    qf.setItalic(lf.lfItalic);
  • trunk/src/gui/text/qfont_x11.cpp

    r2 r561  
    22**
    33** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
    4 ** Contact: Qt Software Information (qt-info@nokia.com)
     4** All rights reserved.
     5** Contact: Nokia Corporation (qt-info@nokia.com)
    56**
    67** This file is part of the QtGui module of the Qt Toolkit.
     
    2122** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    2223**
    23 ** In addition, as a special exception, Nokia gives you certain
    24 ** additional rights. These rights are described in the Nokia Qt LGPL
    25 ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
    26 ** package.
     24** In addition, as a special exception, Nokia gives you certain additional
     25** rights.  These rights are described in the Nokia Qt LGPL Exception
     26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
    2727**
    2828** GNU General Public License Usage
     
    3434** met: http://www.gnu.org/copyleft/gpl.html.
    3535**
    36 ** If you are unsure which license is appropriate for your use, please
    37 ** contact the sales department at qt-sales@nokia.com.
     36** If you have questions regarding the use of this file, please contact
     37** Nokia at qt-info@nokia.com.
    3838** $QT_END_LICENSE$
    3939**
     
    130130int QFontPrivate::defaultEncodingID = -1;
    131131
    132 /*!
    133   Internal function that initializes the font system.
    134 
    135   \internal
    136   The font cache and font dict do not alloc the keys. The key is a QString
    137   which is shared between QFontPrivate and QXFontName.
    138 */
    139132void QFont::initialize()
    140133{
     
    185178}
    186179
    187 /*! \internal
    188 
    189   Internal function that cleans up the font system.
    190 */
    191180void QFont::cleanup()
    192181{
  • trunk/src/gui/text/qfontdatabase.cpp

    r500 r561  
    22**
    33** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
    4 ** Contact: Qt Software Information (qt-info@nokia.com)
     4** All rights reserved.
     5** Contact: Nokia Corporation (qt-info@nokia.com)
    56**
    67** This file is part of the QtGui module of the Qt Toolkit.
     
    2122** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    2223**
    23 ** In addition, as a special exception, Nokia gives you certain
    24 ** additional rights. These rights are described in the Nokia Qt LGPL
    25 ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
    26 ** package.
     24** In addition, as a special exception, Nokia gives you certain additional
     25** rights.  These rights are described in the Nokia Qt LGPL Exception
     26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
    2727**
    2828** GNU General Public License Usage
     
    3434** met: http://www.gnu.org/copyleft/gpl.html.
    3535**
    36 ** If you are unsure which license is appropriate for your use, please
    37 ** contact the sales department at qt-sales@nokia.com.
     36** If you have questions regarding the use of this file, please contact
     37** Nokia at qt-info@nokia.com.
    3838** $QT_END_LICENSE$
    3939**
     
    5858#include <limits.h>
    5959
     60#if (defined(Q_WS_QWS) || defined(Q_OS_SYMBIAN)) && !defined(QT_NO_FREETYPE)
     61#  include <ft2build.h>
     62#  include FT_TRUETYPE_TABLES_H
     63#endif
     64
    6065// #define QFONTDATABASE_DEBUG
    6166#ifdef QFONTDATABASE_DEBUG
     
    8085QT_BEGIN_NAMESPACE
    8186
     87#define SMOOTH_SCALABLE 0xffff
     88
    8289extern int qt_defaultDpiY(); // in qfont.cpp
    8390
    84 Q_GUI_EXPORT bool qt_enable_test_font = false;
     91bool qt_enable_test_font = false;
     92
     93Q_AUTOTEST_EXPORT void qt_setQtEnableTestFont(bool value)
     94{
     95    qt_enable_test_font = value;
     96}
    8597
    8698static int getFontWeight(const QString &weightString)
     
    91103    if (s == QLatin1String("medium") ||
    92104        s == QLatin1String("normal")
    93         || s.compare(qApp->translate("QFontDatabase", "Normal"), Qt::CaseInsensitive) == 0)
     105        || s.compare(QApplication::translate("QFontDatabase", "Normal"), Qt::CaseInsensitive) == 0)
    94106        return QFont::Normal;
    95107    if (s == QLatin1String("bold")
    96         || s.compare(qApp->translate("QFontDatabase", "Bold"), Qt::CaseInsensitive) == 0)
     108        || s.compare(QApplication::translate("QFontDatabase", "Bold"), Qt::CaseInsensitive) == 0)
    97109        return QFont::Bold;
    98110    if (s == QLatin1String("demibold") || s == QLatin1String("demi bold")
    99         || s.compare(qApp->translate("QFontDatabase", "Demi Bold"), Qt::CaseInsensitive) == 0)
     111        || s.compare(QApplication::translate("QFontDatabase", "Demi Bold"), Qt::CaseInsensitive) == 0)
    100112        return QFont::DemiBold;
    101113    if (s == QLatin1String("black")
    102         || s.compare(qApp->translate("QFontDatabase", "Black"), Qt::CaseInsensitive) == 0)
     114        || s.compare(QApplication::translate("QFontDatabase", "Black"), Qt::CaseInsensitive) == 0)
    103115        return QFont::Black;
    104116    if (s == QLatin1String("light"))
     
    106118
    107119    if (s.contains(QLatin1String("bold"))
    108         || s.contains(qApp->translate("QFontDatabase", "Bold"), Qt::CaseInsensitive)) {
     120        || s.contains(QApplication::translate("QFontDatabase", "Bold"), Qt::CaseInsensitive)) {
    109121        if (s.contains(QLatin1String("demi"))
    110             || s.compare(qApp->translate("QFontDatabase", "Demi"), Qt::CaseInsensitive) == 0)
     122            || s.compare(QApplication::translate("QFontDatabase", "Demi"), Qt::CaseInsensitive) == 0)
    111123            return (int) QFont::DemiBold;
    112124        return (int) QFont::Bold;
     
    114126
    115127    if (s.contains(QLatin1String("light"))
    116         || s.compare(qApp->translate("QFontDatabase", "Light"), Qt::CaseInsensitive) == 0)
     128        || s.compare(QApplication::translate("QFontDatabase", "Light"), Qt::CaseInsensitive) == 0)
    117129        return (int) QFont::Light;
    118130
    119131    if (s.contains(QLatin1String("black"))
    120         || s.compare(qApp->translate("QFontDatabase", "Black"), Qt::CaseInsensitive) == 0)
     132        || s.compare(QApplication::translate("QFontDatabase", "Black"), Qt::CaseInsensitive) == 0)
    121133        return (int) QFont::Black;
    122134
     
    148160    QList<QFontDatabase::WritingSystem> systems;
    149161#endif
    150 #if defined(Q_WS_QWS) || defined(Q_WS_PM)
     162#if defined(Q_WS_QWS) || defined(Q_OS_SYMBIAN) || defined(Q_WS_PM)
    151163    QByteArray fileName;
    152164    int fileIndex;
    153 #endif
     165#endif // defined(Q_WS_QWS) || defined(Q_OS_SYMBIAN)
    154166};
    155167
     
    167179    if (!add) return 0;
    168180
    169     if (!(count % 4))
    170         encodings = (QtFontEncoding *)
     181    if (!(count % 4)) {
     182        QtFontEncoding *newEncodings = (QtFontEncoding *)
    171183                    realloc(encodings,
    172184                             (((count+4) >> 2) << 2) * sizeof(QtFontEncoding));
     185        Q_CHECK_PTR(newEncodings);
     186        encodings = newEncodings;
     187    }
    173188    encodings[count].encoding = id;
    174189    encodings[count].xpoint = xpoint;
     
    222237        delete [] setwidthName;
    223238#endif
    224 #if defined(Q_WS_X11) || defined(Q_WS_QWS)
    225         while (count--) {
     239#if defined(Q_WS_X11) || defined(Q_WS_QWS) || defined(Q_OS_SYMBIAN)
     240        while (count) {
     241            // bitfield count-- in while condition does not work correctly in mwccsym2
     242            count--;
    226243#ifdef Q_WS_X11
    227244            free(pixelSizes[count].encodings);
     
    230247            pixelSizes[count].systems.~QList<QFontDatabase::WritingSystem>();
    231248#endif
    232 #if defined(Q_WS_QWS) || defined(Q_WS_PM)
     249#if defined(Q_WS_QWS) || defined(Q_OS_SYMBIAN) || defined(Q_WS_PM)
    233250            pixelSizes[count].fileName.~QByteArray();
    234251#endif
     
    248265    const char *setwidthName;
    249266#endif // Q_WS_X11
    250 #if defined(Q_WS_QWS) || defined(Q_WS_PM)
     267#if defined(Q_WS_QWS) || defined(Q_OS_SYMBIAN) || defined(Q_WS_PM)
    251268    bool antialiased;
    252269#endif
     
    261278
    262279    if (styleString.contains(QLatin1String("Italic"))
    263         || styleString.contains(qApp->translate("QFontDatabase", "Italic")))
     280        || styleString.contains(QApplication::translate("QFontDatabase", "Italic")))
    264281        style = QFont::StyleItalic;
    265282    else if (styleString.contains(QLatin1String("Oblique"))
    266              || styleString.contains(qApp->translate("QFontDatabase", "Oblique")))
     283             || styleString.contains(QApplication::translate("QFontDatabase", "Oblique")))
    267284        style = QFont::StyleOblique;
    268285}
     
    277294        return 0;
    278295
    279     if (!(count % 8))
    280         pixelSizes = (QtFontSize *)
     296    if (!(count % 8)) {
     297        QtFontSize *newPixelSizes = (QtFontSize *)
    281298                     realloc(pixelSizes,
    282299                              (((count+8) >> 3) << 3) * sizeof(QtFontSize));
     300        Q_CHECK_PTR(newPixelSizes);
     301        pixelSizes = newPixelSizes;
     302    }
    283303    pixelSizes[count].pixelSize = size;
    284304#ifdef Q_WS_X11
     
    289309    new (&pixelSizes[count].systems) QList<QFontDatabase::WritingSystem>;
    290310#endif
    291 #if defined(Q_WS_QWS) || defined(Q_WS_PM)
     311#if defined(Q_WS_QWS) || defined(Q_OS_SYMBIAN) || defined(Q_WS_PM)
    292312    new (&pixelSizes[count].fileName) QByteArray;
    293313    pixelSizes[count].fileIndex = 0;
     
    327347                high = pos;
    328348            pos = (high + low) / 2;
    329         };
     349        }
    330350        pos = low;
    331351    }
     
    334354
    335355//     qDebug("adding key (weight=%d, style=%d, oblique=%d stretch=%d) at %d", key.weight, key.style, key.oblique, key.stretch, pos);
    336     if (!(count % 8))
    337         styles = (QtFontStyle **)
     356    if (!(count % 8)) {
     357        QtFontStyle **newStyles = (QtFontStyle **)
    338358                 realloc(styles, (((count+8) >> 3) << 3) * sizeof(QtFontStyle *));
    339 
     359        Q_CHECK_PTR(newStyles);
     360        styles = newStyles;
     361    }
     362
     363    QtFontStyle *style = new QtFontStyle(key);
    340364    memmove(styles + pos + 1, styles + pos, (count-pos)*sizeof(QtFontStyle *));
    341     styles[pos] = new QtFontStyle(key);
     365    styles[pos] = style;
    342366    count++;
    343367    return styles[pos];
     
    371395#endif
    372396        name(n), count(0), foundries(0)
    373 #if defined(Q_WS_QWS)
     397#if defined(Q_WS_QWS) ||   defined(Q_OS_SYMBIAN) && !defined(QT_NO_FREETYPE)
    374398        , bogusWritingSystems(false)
    375399#endif
     
    401425
    402426    QString name;
    403 #ifdef Q_WS_X11
     427#if defined(Q_WS_X11) ||   defined(Q_OS_SYMBIAN) && !defined(QT_NO_FREETYPE)
    404428    QByteArray fontFilename;
    405429    int fontFileIndex;
     
    411435    QtFontFoundry **foundries;
    412436
    413 #ifdef Q_WS_QWS
     437#if defined(Q_WS_QWS) ||   defined(Q_OS_SYMBIAN) && !defined(QT_NO_FREETYPE)
    414438    bool bogusWritingSystems;
    415439    QStringList fallbackFamilies;
     
    444468        return 0;
    445469
    446     if (!(count % 8))
    447         foundries = (QtFontFoundry **)
     470    if (!(count % 8)) {
     471        QtFontFoundry **newFoundries = (QtFontFoundry **)
    448472                    realloc(foundries,
    449473                             (((count+8) >> 3) << 3) * sizeof(QtFontFoundry *));
     474        Q_CHECK_PTR(newFoundries);
     475        foundries = newFoundries;
     476    }
    450477
    451478    foundries[count] = new QtFontFoundry(f);
     
    455482// ### copied to tools/makeqpf/qpf2.cpp
    456483
    457 #if ((defined(Q_WS_QWS) || defined(Q_WS_PM)) && !defined(QT_NO_FREETYPE)) || defined(Q_WS_WIN) || defined(Q_WS_MAC)
     484#if ((defined(Q_WS_QWS) || defined(Q_WS_PM)) && !defined(QT_NO_FREETYPE)) || defined(Q_WS_WIN)  || defined(Q_OS_SYMBIAN) || (defined(Q_WS_MAC) && !defined(QT_MAC_USE_COCOA))
    458485// see the Unicode subset bitfields in the MSDN docs
    459486static int requiredUnicodeBits[QFontDatabase::WritingSystemsCount][2] = {
     
    519546    { 0, 127 }, // same as latin1
    520547        // Other,
    521     { 126, 127 }
     548    { 126, 127 },
     549        // Ogham,
     550    { 78, 127 },
     551        // Runic,
     552    { 79, 127 },
     553        // Nko,
     554    { 14, 127 },
    522555};
    523556
     
    576609#endif
    577610
     611#if defined(Q_OS_SYMBIAN) && defined(QT_NO_FREETYPE)
     612// class with virtual destructor, derived in qfontdatabase_s60.cpp
     613class QFontDatabaseS60Store
     614{
     615public:
     616    virtual ~QFontDatabaseS60Store() {}
     617};
     618#endif
     619
    578620class QFontDatabasePrivate
    579621{
     
    586628#if defined(Q_WS_PM)
    587629        , valid(false)
     630#endif
     631#if defined(Q_OS_SYMBIAN) && defined(QT_NO_FREETYPE)
     632          , s60Store(0)
    588633#endif
    589634    { }
     
    598643        families = 0;
    599644        count = 0;
     645#if defined(Q_OS_SYMBIAN) && defined(QT_NO_FREETYPE)
     646        if (s60Store) {
     647            delete s60Store;
     648            s60Store = 0;
     649        }
     650#endif
    600651        // don't clear the memory fonts!
    601652    }
     
    625676#if defined(Q_WS_QWS)
    626677    bool loadFromCache(const QString &fontPath);
     678    void addQPF2File(const QByteArray &file);
     679#endif // Q_WS_QWS
     680#if defined(Q_WS_QWS) ||   defined(Q_OS_SYMBIAN) && !defined(QT_NO_FREETYPE)
    627681    void addFont(const QString &familyname, const char *foundryname, int weight,
    628682                 bool italic, int pixelSize, const QByteArray &file, int fileIndex,
    629683                 bool antialiased,
    630684                 const QList<QFontDatabase::WritingSystem> &writingSystems = QList<QFontDatabase::WritingSystem>());
    631     void addQPF2File(const QByteArray &file);
    632685#ifndef QT_NO_FREETYPE
    633686    QStringList addTTFile(const QByteArray &file, const QByteArray &fontData = QByteArray());
    634 #endif
    635 
     687#endif // QT_NO_FREETYPE
     688#endif
     689#if defined(Q_WS_QWS)
    636690    QDataStream *stream;
    637691    QStringList fallbackFamilies;
     692#elif defined(Q_OS_SYMBIAN) && defined(QT_NO_FREETYPE)
     693    const QFontDatabaseS60Store *s60Store;
    638694#endif
    639695
     
    666722                low = pos;
    667723            pos = (high + low) / 2;
    668         };
     724        }
    669725        if (!res)
    670726            return families[pos];
     
    677733
    678734    // qDebug("adding family %s at %d total=%d", f.latin1(), pos, count);
    679     if (!(count % 8))
    680         families = (QtFontFamily **)
     735    if (!(count % 8)) {
     736        QtFontFamily **newFamilies = (QtFontFamily **)
    681737                   realloc(families,
    682738                            (((count+8) >> 3) << 3) * sizeof(QtFontFamily *));
    683 
     739        Q_CHECK_PTR(newFamilies);
     740        families = newFamilies;
     741    }
     742
     743    QtFontFamily *family = new QtFontFamily(f);
    684744    memmove(families + pos + 1, families + pos, (count-pos)*sizeof(QtFontFamily *));
    685     families[pos] = new QtFontFamily(f);
     745    families[pos] = family;
    686746    count++;
    687747    return families[pos];
    688748}
    689749
     750#if defined(Q_WS_QWS) ||   defined(Q_OS_SYMBIAN) && !defined(QT_NO_FREETYPE)
     751void QFontDatabasePrivate::addFont(const QString &familyname, const char *foundryname, int weight, bool italic, int pixelSize,
     752                                   const QByteArray &file, int fileIndex, bool antialiased,
     753                                   const QList<QFontDatabase::WritingSystem> &writingSystems)
     754{
     755//    qDebug() << "Adding font" << familyname << weight << italic << pixelSize << file << fileIndex << antialiased;
     756    QtFontStyle::Key styleKey;
     757    styleKey.style = italic ? QFont::StyleItalic : QFont::StyleNormal;
     758    styleKey.weight = weight;
     759    styleKey.stretch = 100;
     760    QtFontFamily *f = family(familyname, true);
     761
     762    if (writingSystems.isEmpty()) {
     763        for (int ws = 1; ws < QFontDatabase::WritingSystemsCount; ++ws) {
     764            f->writingSystems[ws] = QtFontFamily::Supported;
     765        }
     766        f->bogusWritingSystems = true;
     767    } else {
     768        for (int i = 0; i < writingSystems.count(); ++i) {
     769            f->writingSystems[writingSystems.at(i)] = QtFontFamily::Supported;
     770        }
     771    }
     772
     773    QtFontFoundry *foundry = f->foundry(QString::fromLatin1(foundryname), true);
     774    QtFontStyle *style = foundry->style(styleKey,  true);
     775    style->smoothScalable = (pixelSize == 0);
     776    style->antialiased = antialiased;
     777    QtFontSize *size = style->pixelSize(pixelSize?pixelSize:SMOOTH_SCALABLE, true);
     778    size->fileName = file;
     779    size->fileIndex = fileIndex;
     780
     781#if defined(Q_WS_QWS)
     782    if (stream) {
     783        *stream << familyname << foundry->name << weight << quint8(italic) << pixelSize
     784                << file << fileIndex << quint8(antialiased);
     785        *stream << quint8(writingSystems.count());
     786        for (int i = 0; i < writingSystems.count(); ++i)
     787            *stream << quint8(writingSystems.at(i));
     788    }
     789#else // ..in case of defined(Q_OS_SYMBIAN) && !defined(QT_NO_FREETYPE)
     790    f->fontFilename = file;
     791    f->fontFileIndex = fileIndex;
     792#endif
     793}
     794#endif
     795
     796#if (defined(Q_WS_QWS) || defined(Q_OS_SYMBIAN)) && !defined(QT_NO_FREETYPE)
     797QStringList QFontDatabasePrivate::addTTFile(const QByteArray &file, const QByteArray &fontData)
     798{
     799    QStringList families;
     800    extern FT_Library qt_getFreetype();
     801    FT_Library library = qt_getFreetype();
     802
     803    int index = 0;
     804    int numFaces = 0;
     805    do {
     806        FT_Face face;
     807        FT_Error error;
     808        if (!fontData.isEmpty()) {
     809            error = FT_New_Memory_Face(library, (const FT_Byte *)fontData.constData(), fontData.size(), index, &face);
     810        } else {
     811            error = FT_New_Face(library, file, index, &face);
     812        }
     813        if (error != FT_Err_Ok) {
     814            qDebug() << "FT_New_Face failed with index" << index << ":" << hex << error;
     815            break;
     816        }
     817        numFaces = face->num_faces;
     818
     819        int weight = QFont::Normal;
     820        bool italic = face->style_flags & FT_STYLE_FLAG_ITALIC;
     821
     822        if (face->style_flags & FT_STYLE_FLAG_BOLD)
     823            weight = QFont::Bold;
     824
     825        QList<QFontDatabase::WritingSystem> writingSystems;
     826        // detect symbol fonts
     827        for (int i = 0; i < face->num_charmaps; ++i) {
     828            FT_CharMap cm = face->charmaps[i];
     829            if (cm->encoding == ft_encoding_adobe_custom
     830                    || cm->encoding == ft_encoding_symbol) {
     831                writingSystems.append(QFontDatabase::Symbol);
     832                break;
     833            }
     834        }
     835        if (writingSystems.isEmpty()) {
     836            TT_OS2 *os2 = (TT_OS2 *)FT_Get_Sfnt_Table(face, ft_sfnt_os2);
     837            if (os2) {
     838                quint32 unicodeRange[4] = {
     839                    os2->ulUnicodeRange1, os2->ulUnicodeRange2, os2->ulUnicodeRange3, os2->ulUnicodeRange4
     840                };
     841                quint32 codePageRange[2] = {
     842                    os2->ulCodePageRange1, os2->ulCodePageRange2
     843                };
     844
     845                writingSystems = determineWritingSystemsFromTrueTypeBits(unicodeRange, codePageRange);
     846                //for (int i = 0; i < writingSystems.count(); ++i)
     847                //    qDebug() << QFontDatabase::writingSystemName(writingSystems.at(i));
     848            }
     849        }
     850
     851        QString family = QString::fromAscii(face->family_name);
     852        families.append(family);
     853        addFont(family, /*foundry*/ "", weight, italic,
     854                /*pixelsize*/ 0, file, index, /*antialias*/ true, writingSystems);
     855
     856        FT_Done_Face(face);
     857        ++index;
     858    } while (index < numFaces);
     859    return families;
     860}
     861#endif
    690862
    691863static const int scriptForWritingSystem[] = {
     
    730902    QUnicodeTables::Common, // Symbol
    731903    QUnicodeTables::Ogham,  // Ogham
    732     QUnicodeTables::Runic // Runic
     904    QUnicodeTables::Runic, // Runic
     905    QUnicodeTables::Nko // Nko
    733906};
    734907
     
    738911{
    739912    return ((writingSystem >= QFontDatabase::Syriac && writingSystem <= QFontDatabase::Sinhala)
    740             || writingSystem == QFontDatabase::Khmer);
     913            || writingSystem == QFontDatabase::Khmer || writingSystem == QFontDatabase::Nko);
    741914}
    742915static inline bool scriptRequiresOpenType(int script)
    743916{
    744917    return ((script >= QUnicodeTables::Syriac && script <= QUnicodeTables::Sinhala)
    745             || script == QUnicodeTables::Khmer);
     918            || script == QUnicodeTables::Khmer || script == QUnicodeTables::Nko);
    746919}
    747920#endif
     
    806979static void match(int script, const QFontDef &request,
    807980                  const QString &family_name, const QString &foundry_name, int force_encoding_id,
    808                   QtFontDesc *desc, const QList<int> &blacklistedFamilies = QList<int>());
     981                  QtFontDesc *desc, const QList<int> &blacklistedFamilies = QList<int>(), bool forceXLFD=false);
    809982
    810983#if defined(Q_WS_X11) || defined(Q_WS_QWS)
     
    815988        fontDef->family += QString::fromLatin1(" [");
    816989        fontDef->family += desc.foundry->name;
    817         fontDef->family += QString::fromLatin1("]");
     990        fontDef->family += QLatin1Char(']');
    818991    }
    819992
     
    8371010#endif
    8381011
    839 #if defined(Q_WS_X11) || defined(Q_WS_WIN) || defined(Q_WS_PM)
     1012#if defined(Q_WS_X11) || defined(Q_WS_WIN) || defined(Q_OS_SYMBIAN) || defined(Q_WS_PM)
    8401013static void getEngineData(const QFontPrivate *d, const QFontCache::Key &key)
    8411014{
     
    8501023    }
    8511024}
     1025#endif
    8521026
    8531027static QStringList familyList(const QFontDef &req)
     
    8781052    return family_list;
    8791053}
    880 #endif
    8811054
    8821055Q_GLOBAL_STATIC(QFontDatabasePrivate, privateDb)
     
    9001073#elif defined(Q_WS_QWS)
    9011074#  include "qfontdatabase_qws.cpp"
     1075#elif defined(Q_OS_SYMBIAN)
     1076#  include "qfontdatabase_s60.cpp"
    9021077#endif
    9031078QT_END_INCLUDE_NAMESPACE
     
    12041379static void match(int script, const QFontDef &request,
    12051380                  const QString &family_name, const QString &foundry_name, int force_encoding_id,
    1206                   QtFontDesc *desc, const QList<int> &blacklistedFamilies)
     1381                  QtFontDesc *desc, const QList<int> &blacklistedFamilies, bool forceXLFD)
    12071382{
    12081383    Q_UNUSED(force_encoding_id);
     
    12191394             "    weight: %d, style: %d\n"
    12201395             "    stretch: %d\n"
    1221              "    pixelSize: %d\n"
     1396             "    pixelSize: %g\n"
    12221397             "    pitch: %c",
    12231398             family_name.isEmpty() ? "-- first in script --" : family_name.toLatin1().constData(),
     
    12391414    unsigned int score = ~0u;
    12401415
     1416#ifdef Q_WS_X11
     1417    load(family_name, script, forceXLFD);
     1418#else
     1419    Q_UNUSED(forceXLFD);
    12411420    load(family_name, script);
     1421#endif
    12421422
    12431423    QFontDatabasePrivate *db = privateDb();
     
    13031483    QString result;
    13041484    if (weight >= QFont::Black)
    1305         result = qApp->translate("QFontDatabase", "Black");
     1485        result = QApplication::translate("QFontDatabase", "Black");
    13061486    else if (weight >= QFont::Bold)
    1307         result = qApp->translate("QFontDatabase", "Bold");
     1487        result = QApplication::translate("QFontDatabase", "Bold");
    13081488    else if (weight >= QFont::DemiBold)
    1309         result = qApp->translate("QFontDatabase", "Demi Bold");
     1489        result = QApplication::translate("QFontDatabase", "Demi Bold");
    13101490    else if (weight < QFont::Normal)
    1311         result = qApp->translate("QFontDatabase", "Light");
     1491        result = QApplication::translate("QFontDatabase", "Light");
    13121492
    13131493    if (style == QFont::StyleItalic)
    1314         result += QLatin1Char(' ') + qApp->translate("QFontDatabase", "Italic");
     1494        result += QLatin1Char(' ') + QApplication::translate("QFontDatabase", "Italic");
    13151495    else if (style == QFont::StyleOblique)
    1316         result += QLatin1Char(' ') + qApp->translate("QFontDatabase", "Oblique");
     1496        result += QLatin1Char(' ') + QApplication::translate("QFontDatabase", "Oblique");
    13171497
    13181498    if (result.isEmpty())
    1319         result = qApp->translate("QFontDatabase", "Normal");
     1499        result = QApplication::translate("QFontDatabase", "Normal");
    13201500
    13211501    return result.simplified();
     
    13491529    \brief The QFontDatabase class provides information about the fonts available in the underlying window system.
    13501530
    1351     \ingroup environment
    1352     \ingroup multimedia
    1353     \ingroup text
     1531    \ingroup appearance
    13541532
    13551533    The most common uses of this class are to query the database for
     
    13601538
    13611539    If the font family is available from two or more foundries the
    1362     foundry name is included in the family name, e.g. "Helvetica
    1363     [Adobe]" and "Helvetica [Cronyx]". When you specify a family you
    1364     can either use the old hyphenated Qt 2.x "foundry-family" format,
    1365     e.g. "Cronyx-Helvetica", or the new bracketed Qt 3.x "family
    1366     [foundry]" format e.g. "Helvetica [Cronyx]". If the family has a
    1367     foundry it is always returned, e.g. by families(), using the
    1368     bracketed format.
     1540    foundry name is included in the family name; for example:
     1541    "Helvetica [Adobe]" and "Helvetica [Cronyx]". When you specify a
     1542    family, you can either use the old hyphenated "foundry-family"
     1543    format or the bracketed "family [foundry]" format; for example:
     1544    "Cronyx-Helvetica" or "Helvetica [Cronyx]". If the family has a
     1545    foundry it is always returned using the bracketed format, as is
     1546    the case with the value returned by families().
    13691547
    13701548    The font() function returns a QFont given a family, style and
     
    14431621    \value Ogham
    14441622    \value Runic
     1623    \value Nko
    14451624
    14461625    \omitvalue WritingSystemsCount
     
    15491728                    str += QLatin1String(" [");
    15501729                    str += foundry;
    1551                     str += QLatin1String("]");
     1730                    str += QLatin1Char(']');
    15521731                }
    15531732                flist.append(str);
     
    21172296        name = QT_TRANSLATE_NOOP("QFontDatabase", "Runic");
    21182297        break;
     2298    case Nko:
     2299        name = QT_TRANSLATE_NOOP("QFontDatabase", "N'Ko");
     2300        break;
    21192301    default:
    21202302        Q_ASSERT_X(false, "QFontDatabase::writingSystemName", "invalid 'writingSystem' parameter");
    21212303        break;
    21222304    }
    2123     return qApp ? qApp->translate("QFontDatabase", name) : QString::fromLatin1(name);
     2305    return QApplication::translate("QFontDatabase", name);
    21242306}
    21252307
     
    23082490        break;
    23092491    case Vietnamese:
    2310         break;
     2492    {
     2493        static const char vietnameseUtf8[] = {
     2494            char(0xef), char(0xbb), char(0xbf), char(0xe1), char(0xbb), char(0x97),
     2495            char(0xe1), char(0xbb), char(0x99),
     2496            char(0xe1), char(0xbb), char(0x91),
     2497            char(0xe1), char(0xbb), char(0x93),
     2498        };
     2499        sample += QString::fromUtf8(vietnameseUtf8, sizeof(vietnameseUtf8));
     2500        break;
     2501    }
    23112502    case Ogham:
    23122503        sample += QChar(0x1681);
     
    23202511        sample += QChar(0x16a2);
    23212512        sample += QChar(0x16a3);
     2513        break;
     2514    case Nko:
     2515        sample += QChar(0x7ca);
     2516        sample += QChar(0x7cb);
     2517        sample += QChar(0x7cc);
     2518        sample += QChar(0x7cd);
    23222519        break;
    23232520    default:
     
    24812678    will not produce readable output.
    24822679
    2483     \sa threads.html#painting-in-threads
     2680    \sa {Thread-Support in Qt Modules#Painting In Threads}{Painting In Threads}
    24842681*/
    24852682
  • trunk/src/gui/text/qfontdatabase.h

    r2 r561  
    22**
    33** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
    4 ** Contact: Qt Software Information (qt-info@nokia.com)
     4** All rights reserved.
     5** Contact: Nokia Corporation (qt-info@nokia.com)
    56**
    67** This file is part of the QtGui module of the Qt Toolkit.
     
    2122** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    2223**
    23 ** In addition, as a special exception, Nokia gives you certain
    24 ** additional rights. These rights are described in the Nokia Qt LGPL
    25 ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
    26 ** package.
     24** In addition, as a special exception, Nokia gives you certain additional
     25** rights.  These rights are described in the Nokia Qt LGPL Exception
     26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
    2727**
    2828** GNU General Public License Usage
     
    3434** met: http://www.gnu.org/copyleft/gpl.html.
    3535**
    36 ** If you are unsure which license is appropriate for your use, please
    37 ** contact the sales department at qt-sales@nokia.com.
     36** If you have questions regarding the use of this file, please contact
     37** Nokia at qt-info@nokia.com.
    3838** $QT_END_LICENSE$
    3939**
     
    109109        Ogham,
    110110        Runic,
     111        Nko,
    111112
    112113        WritingSystemsCount
     
    152153    static void createDatabase();
    153154    static void parseFontName(const QString &name, QString &foundry, QString &family);
    154 #if defined(Q_WS_QWS)
     155#if defined(Q_WS_QWS) || defined(Q_OS_SYMBIAN)
    155156    static QFontEngine *findFont(int script, const QFontPrivate *fp, const QFontDef &request);
    156157#endif
     
    166167    friend class QFontEngineMultiXLFD;
    167168    friend class QFontEngineMultiQWS;
     169    friend class QFontEngineMultiS60;
    168170
    169171    QFontDatabasePrivate *d;
  • trunk/src/gui/text/qfontdatabase_mac.cpp

    r2 r561  
    22**
    33** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
    4 ** Contact: Qt Software Information (qt-info@nokia.com)
     4** All rights reserved.
     5** Contact: Nokia Corporation (qt-info@nokia.com)
    56**
    67** This file is part of the QtGui module of the Qt Toolkit.
     
    2122** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    2223**
    23 ** In addition, as a special exception, Nokia gives you certain
    24 ** additional rights. These rights are described in the Nokia Qt LGPL
    25 ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
    26 ** package.
     24** In addition, as a special exception, Nokia gives you certain additional
     25** rights.  These rights are described in the Nokia Qt LGPL Exception
     26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
    2727**
    2828** GNU General Public License Usage
     
    3434** met: http://www.gnu.org/copyleft/gpl.html.
    3535**
    36 ** If you are unsure which license is appropriate for your use, please
    37 ** contact the sales department at qt-sales@nokia.com.
     36** If you have questions regarding the use of this file, please contact
     37** Nokia at qt-info@nokia.com.
    3838** $QT_END_LICENSE$
    3939**
     
    5252int qt_mac_pointsize(const QFontDef &def, int dpi); //qfont_mac.cpp
    5353
     54#ifndef QT_MAC_USE_COCOA
    5455static void initWritingSystems(QtFontFamily *family, ATSFontRef atsFont)
    5556{
     
    8283        family->writingSystems[systems.at(i)] = QtFontFamily::Supported;
    8384}
     85#endif
    8486
    8587static void initializeDb()
     
    151153#endif
    152154    {
    153 #ifndef Q_WS_MAC64
     155#ifndef QT_MAC_USE_COCOA
    154156        FMFontIterator it;
    155157        if (!FMCreateFontIterator(0, 0, kFMUseGlobalScopeOption, &it)) {
     
    282284
    283285    //find the font
    284     QStringList family_list = req.family.split(QLatin1Char(','));
    285     // append the substitute list for each family in family_list
    286     {
    287             QStringList subs_list;
    288             for(QStringList::ConstIterator it = family_list.constBegin(); it != family_list.constEnd(); ++it)
    289                     subs_list += QFont::substitutes(*it);
    290             family_list += subs_list;
    291     }
     286    QStringList family_list = familyList(req);
    292287
    293288    const char *stylehint = styleHint(req);
     
    314309                    fontRef = ATSFontFindFromName(QCFString(db->families[k]->name), kATSOptionFlagsDefault);
    315310                    goto FamilyFound;
     311                } else {
     312#if defined(QT_MAC_USE_COCOA)
     313                    // ATS and CT disagrees on what the family name should be,
     314                    // use CT to look up the font if ATS fails.
     315                    QCFString familyName = QString::fromAscii(family_name);
     316                    QCFType<CTFontRef> CTfontRef = CTFontCreateWithName(familyName, 12, NULL);
     317                    QCFType<CTFontDescriptorRef> fontDescriptor = CTFontCopyFontDescriptor(CTfontRef);
     318                    QCFString displayName = (CFStringRef)CTFontDescriptorCopyAttribute(fontDescriptor, kCTFontDisplayNameAttribute);
     319
     320                    familyRef = ATSFontFamilyFindFromName(displayName, kATSOptionFlagsDefault);
     321                    if (familyRef) {
     322                        fontRef = ATSFontFindFromName(displayName, kATSOptionFlagsDefault);
     323                        goto FamilyFound;
     324                    }
     325#endif
    316326                }
    317327            }
     
    462472
    463473    fnt->families.clear();
     474#if defined(QT_MAC_USE_COCOA)
     475    // Make sure that the family name set on the font matches what
     476    // kCTFontFamilyNameAttribute returns in initializeDb().
     477    // So far the best solution seems find the installed font
     478    // using CoreText and get the family name from it.
     479    // (ATSFontFamilyGetName appears to be the correct API, but also
     480    // returns the font display name.)
     481    for(int i = 0; i < containedFonts.size(); ++i) {
     482        QCFString fontPostScriptName;
     483        ATSFontGetPostScriptName(containedFonts[i], kATSOptionFlagsDefault, &fontPostScriptName);
     484        QCFType<CTFontDescriptorRef> font = CTFontDescriptorCreateWithNameAndSize(fontPostScriptName, 14);
     485        QCFString familyName = (CFStringRef)CTFontDescriptorCopyAttribute(font, kCTFontFamilyNameAttribute);
     486        fnt->families.append(familyName);
     487    }
     488#else
    464489    for(int i = 0; i < containedFonts.size(); ++i) {
    465490        QCFString family;
     
    467492        fnt->families.append(family);
    468493    }
     494#endif
    469495
    470496    fnt->handle = handle;
  • trunk/src/gui/text/qfontdatabase_win.cpp

    r2 r561  
    22**
    33** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
    4 ** Contact: Qt Software Information (qt-info@nokia.com)
     4** All rights reserved.
     5** Contact: Nokia Corporation (qt-info@nokia.com)
    56**
    67** This file is part of the QtGui module of the Qt Toolkit.
     
    2122** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    2223**
    23 ** In addition, as a special exception, Nokia gives you certain
    24 ** additional rights. These rights are described in the Nokia Qt LGPL
    25 ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
    26 ** package.
     24** In addition, as a special exception, Nokia gives you certain additional
     25** rights.  These rights are described in the Nokia Qt LGPL Exception
     26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
    2727**
    2828** GNU General Public License Usage
     
    3434** met: http://www.gnu.org/copyleft/gpl.html.
    3535**
    36 ** If you are unsure which license is appropriate for your use, please
    37 ** contact the sales department at qt-sales@nokia.com.
     36** If you have questions regarding the use of this file, please contact
     37** Nokia at qt-info@nokia.com.
    3838** $QT_END_LICENSE$
    3939**
     
    4141
    4242#include "qt_windows.h"
     43#include <qmath.h>
    4344#include <private/qapplication_p.h>
    4445#include "qfont_p.h"
     
    196197
    197198    HDC hdc = GetDC( 0 );
    198     HFONT hfont;
    199     QT_WA( {
    200         LOGFONTW lf;
    201         memset( &lf, 0, sizeof( LOGFONTW ) );
    202         memcpy( lf.lfFaceName, familyName.utf16(), qMin(LF_FACESIZE, familyName.length())*sizeof(QChar) );
    203         lf.lfCharSet = DEFAULT_CHARSET;
    204         hfont = CreateFontIndirectW( &lf );
    205     }, {
    206         LOGFONTA lf;
    207         memset( &lf, 0, sizeof( LOGFONTA ) );
    208         QByteArray lfam = familyName.toLocal8Bit();
    209         memcpy( lf.lfFaceName, lfam, qMin(LF_FACESIZE, lfam.size()) );
    210         lf.lfCharSet = DEFAULT_CHARSET;
    211         hfont = CreateFontIndirectA( &lf );
    212     } );
     199    LOGFONT lf;
     200    memset(&lf, 0, sizeof(LOGFONT));
     201    memcpy(lf.lfFaceName, familyName.utf16(), qMin(LF_FACESIZE, familyName.length()) * sizeof(wchar_t));
     202    lf.lfCharSet = DEFAULT_CHARSET;
     203    HFONT hfont = CreateFontIndirect(&lf);
     204
    213205    if(!hfont) {
    214206        ReleaseDC(0, hdc);
     
    246238}
    247239
    248 static void getFontSignature(const QString &familyName,
    249                              NEWTEXTMETRICEX *textmetric,
    250                              FONTSIGNATURE *signature)
    251 {
    252     QT_WA({
    253         Q_UNUSED(familyName);
    254         *signature = textmetric->ntmFontSig;
    255     }, {
    256         // the textmetric structure we get from EnumFontFamiliesEx on Win9x has
    257         // a FONTSIGNATURE, but that one is uninitialized and doesn't work. Have to go
    258         // the hard way and load the font to find out.
    259         HDC hdc = GetDC(0);
    260         LOGFONTA lf;
    261         memset(&lf, 0, sizeof(LOGFONTA));
    262         QByteArray lfam = familyName.toLocal8Bit();
    263         memcpy(lf.lfFaceName, lfam.data(), qMin(LF_FACESIZE, lfam.length()));
    264         lf.lfCharSet = DEFAULT_CHARSET;
    265         HFONT hfont = CreateFontIndirectA(&lf);
    266         HGDIOBJ oldobj = SelectObject(hdc, hfont);
    267         GetTextCharsetInfo(hdc, signature, 0);
    268         SelectObject(hdc, oldobj);
    269         DeleteObject(hfont);
    270         ReleaseDC(0, hdc);
    271     });
    272 }
    273 
    274240static
    275241void addFontToDatabase(QString familyName, const QString &scriptName,
     
    289255    int size;
    290256
    291 //    QString escript = QString::fromUtf16((ushort *)f->elfScript);
     257//    QString escript = QString::fromWCharArray(f->elfScript);
    292258//    qDebug("script=%s", escript.latin1());
    293259
    294     QT_WA({
    295         NEWTEXTMETRIC *tm = (NEWTEXTMETRIC *)textmetric;
    296         fixed = !(tm->tmPitchAndFamily & TMPF_FIXED_PITCH);
    297         ttf = (tm->tmPitchAndFamily & TMPF_TRUETYPE);
    298         scalable = tm->tmPitchAndFamily & (TMPF_VECTOR|TMPF_TRUETYPE);
    299         size = scalable ? SMOOTH_SCALABLE : tm->tmHeight;
    300         italic = tm->tmItalic;
    301         weight = tm->tmWeight;
    302     } , {
    303         NEWTEXTMETRICA *tm = (NEWTEXTMETRICA *)textmetric;
    304         fixed = !(tm->tmPitchAndFamily & TMPF_FIXED_PITCH);
    305         ttf = (tm->tmPitchAndFamily & TMPF_TRUETYPE);
    306         scalable = tm->tmPitchAndFamily & (TMPF_VECTOR|TMPF_TRUETYPE);
    307         size = scalable ? SMOOTH_SCALABLE : tm->tmHeight;
    308         italic = tm->tmItalic;
    309         weight = tm->tmWeight;
    310     });
     260    NEWTEXTMETRIC *tm = (NEWTEXTMETRIC *)textmetric;
     261    fixed = !(tm->tmPitchAndFamily & TMPF_FIXED_PITCH);
     262    ttf = (tm->tmPitchAndFamily & TMPF_TRUETYPE);
     263    scalable = tm->tmPitchAndFamily & (TMPF_VECTOR|TMPF_TRUETYPE);
     264    size = scalable ? SMOOTH_SCALABLE : tm->tmHeight;
     265    italic = tm->tmItalic;
     266    weight = tm->tmWeight;
     267
    311268    // the "@family" fonts are just the same as "family". Ignore them.
    312269    if (familyName[0] != QLatin1Char('@') && !familyName.startsWith(QLatin1String("WST_"))) {
     
    365322                signature->fsUsb[2], signature->fsUsb[3]
    366323            };
    367 #ifdef Q_OS_WINCE
     324#ifdef Q_WS_WINCE
    368325            if (signature->fsUsb[0] == 0) {
    369326                // If the unicode ranges bit mask is zero then
     
    421378storeFont(ENUMLOGFONTEX* f, NEWTEXTMETRICEX *textmetric, int type, LPARAM /*p*/)
    422379{
    423     QString familyName;
    424     QT_WA({
    425         familyName = QString::fromUtf16((ushort*)f->elfLogFont.lfFaceName);
    426     },{
    427         ENUMLOGFONTEXA *fa = (ENUMLOGFONTEXA *)f;
    428         familyName = QString::fromLocal8Bit(fa->elfLogFont.lfFaceName);
    429     });
    430     QString script = QT_WA_INLINE(QString::fromUtf16((const ushort *)f->elfScript),
    431                                   QString::fromLocal8Bit((const char *)((ENUMLOGFONTEXA *)f)->elfScript));
    432 
    433     FONTSIGNATURE signature;
    434     getFontSignature(familyName, textmetric, &signature);
     380    QString familyName = QString::fromWCharArray(f->elfLogFont.lfFaceName);
     381    QString script = QString::fromWCharArray(f->elfScript);
     382
     383    FONTSIGNATURE signature = textmetric->ntmFontSig;
    435384
    436385    // NEWTEXTMETRICEX is a NEWTEXTMETRIC, which according to the documentation is
     
    460409    HDC dummy = GetDC(0);
    461410
    462     QT_WA({
    463         LOGFONT lf;
    464         lf.lfCharSet = DEFAULT_CHARSET;
    465         if (fam.isNull()) {
    466             lf.lfFaceName[0] = 0;
    467         } else {
    468             memcpy(lf.lfFaceName, fam.utf16(), sizeof(TCHAR)*qMin(fam.length()+1,32));  // 32 = Windows hard-coded
    469         }
    470         lf.lfPitchAndFamily = 0;
    471 
    472         EnumFontFamiliesEx(dummy, &lf,
    473             (FONTENUMPROC)storeFont, (LPARAM)privateDb(), 0);
    474     } , {
    475         LOGFONTA lf;
    476         lf.lfCharSet = DEFAULT_CHARSET;
    477         if (fam.isNull()) {
    478             lf.lfFaceName[0] = 0;
    479         } else {
    480             QByteArray lname = fam.toLocal8Bit();
    481             memcpy(lf.lfFaceName,lname.data(),
    482                 qMin(lname.length()+1,32));  // 32 = Windows hard-coded
    483         }
    484         lf.lfPitchAndFamily = 0;
    485 
    486         EnumFontFamiliesExA(dummy, &lf,
    487             (FONTENUMPROCA)storeFont, (LPARAM)privateDb(), 0);
    488     });
     411    LOGFONT lf;
     412    lf.lfCharSet = DEFAULT_CHARSET;
     413    if (fam.isNull()) {
     414        lf.lfFaceName[0] = 0;
     415    } else {
     416        memcpy(lf.lfFaceName, fam.utf16(), sizeof(wchar_t) * qMin(fam.length() + 1, 32));  // 32 = Windows hard-coded
     417    }
     418    lf.lfPitchAndFamily = 0;
     419
     420    EnumFontFamiliesEx(dummy, &lf,
     421        (FONTENUMPROC)storeFont, (LPARAM)privateDb(), 0);
    489422
    490423    ReleaseDC(0, dummy);
     
    497430            const QString familyName = fnt.families.at(j);
    498431            HDC hdc = GetDC(0);
    499             HFONT hfont;
    500             QT_WA({
    501                 LOGFONTW lf;
    502                 memset(&lf, 0, sizeof(LOGFONTW));
    503                 memcpy(lf.lfFaceName, familyName.utf16(), qMin(LF_FACESIZE, familyName.size()));
    504                 lf.lfCharSet = DEFAULT_CHARSET;
    505                 hfont = CreateFontIndirectW(&lf);
    506             } , {
    507                 LOGFONTA lf;
    508                 memset(&lf, 0, sizeof(LOGFONTA));
    509                 QByteArray lfam = familyName.toLocal8Bit();
    510                 memcpy(lf.lfFaceName, lfam.data(), qMin(LF_FACESIZE, lfam.length()));
    511                 lf.lfCharSet = DEFAULT_CHARSET;
    512                 hfont = CreateFontIndirectA(&lf);
    513             });
     432            LOGFONT lf;
     433            memset(&lf, 0, sizeof(LOGFONT));
     434            memcpy(lf.lfFaceName, familyName.utf16(), sizeof(wchar_t) * qMin(LF_FACESIZE, familyName.size()));
     435            lf.lfCharSet = DEFAULT_CHARSET;
     436            HFONT hfont = CreateFontIndirect(&lf);
    514437            HGDIOBJ oldobj = SelectObject(hdc, hfont);
    515438
     
    550473    for (int f = 0; f < db->count; f++) {
    551474        QtFontFamily *family = db->families[f];
    552         qDebug("    %s: %p", family->name.latin1(), family);
     475        qDebug("    %s: %p", qPrintable(family->name), family);
    553476        populate_database(family->name);
    554477
     
    599522    HDC dc = ((request.styleStrategy & QFont::PreferDevice) && fp->hdc) ? fp->hdc : shared_dc();
    600523    SelectObject(dc, fe->hfont);
    601     QT_WA({
    602         TCHAR n[64];
    603         GetTextFaceW(dc, 64, n);
    604         fe->fontDef.family = QString::fromUtf16((ushort*)n);
    605         fe->fontDef.fixedPitch = !(fe->tm.w.tmPitchAndFamily & TMPF_FIXED_PITCH);
    606     } , {
    607         char an[64];
    608         GetTextFaceA(dc, 64, an);
    609         fe->fontDef.family = QString::fromLocal8Bit(an);
    610         fe->fontDef.fixedPitch = !(fe->tm.a.tmPitchAndFamily & TMPF_FIXED_PITCH);
    611     });
     524    wchar_t n[64];
     525    GetTextFace(dc, 64, n);
     526    fe->fontDef.family = QString::fromWCharArray(n);
     527    fe->fontDef.fixedPitch = !(fe->tm.tmPitchAndFamily & TMPF_FIXED_PITCH);
    612528    if (fe->fontDef.pointSize < 0) {
    613529        fe->fontDef.pointSize = fe->fontDef.pixelSize * 72. / fp->dpi;
     
    700616
    701617    bool stockFont = false;
     618    bool preferClearTypeAA = false;
    702619
    703620    HFONT hfont = 0;
    704621
    705622    if (fp->rawMode) {                        // will choose a stock font
    706         int f, deffnt;
    707         // ### why different?
    708         if ((QSysInfo::WindowsVersion & QSysInfo::WV_NT_based) || QSysInfo::WindowsVersion == QSysInfo::WV_32s)
    709             deffnt = SYSTEM_FONT;
    710         else
    711             deffnt = DEFAULT_GUI_FONT;
     623        int f, deffnt = SYSTEM_FONT;
    712624        QString fam = desc->family->name.toLower();
    713625        if (fam == QLatin1String("default"))
     
    715627        else if (fam == QLatin1String("system"))
    716628            f = SYSTEM_FONT;
    717 #ifndef Q_OS_WINCE
     629#ifndef Q_WS_WINCE
    718630        else if (fam == QLatin1String("system_fixed"))
    719631            f = SYSTEM_FIXED_FONT;
     
    760672        }
    761673
    762         lf.lfHeight = -request.pixelSize;
     674        lf.lfHeight = -qRound(request.pixelSize);
    763675        lf.lfWidth                = 0;
    764676        lf.lfEscapement        = 0;
     
    774686        if (request.styleStrategy & QFont::PreferBitmap) {
    775687            strat = OUT_RASTER_PRECIS;
    776 #ifndef Q_OS_WINCE
     688#ifndef Q_WS_WINCE
    777689        } else if (request.styleStrategy & QFont::PreferDevice) {
    778690            strat = OUT_DEVICE_PRECIS;
    779691        } else if (request.styleStrategy & QFont::PreferOutline) {
    780             QT_WA({
    781                 strat = OUT_OUTLINE_PRECIS;
    782             } , {
    783                 strat = OUT_TT_PRECIS;
    784             });
     692            strat = OUT_OUTLINE_PRECIS;
    785693        } else if (request.styleStrategy & QFont::ForceOutline) {
    786694            strat = OUT_TT_ONLY_PRECIS;
     
    794702        if (request.styleStrategy & QFont::PreferMatch)
    795703            qual = DRAFT_QUALITY;
    796 #ifndef Q_OS_WINCE
     704#ifndef Q_WS_WINCE
    797705        else if (request.styleStrategy & QFont::PreferQuality)
    798706            qual = PROOF_QUALITY;
     
    800708
    801709        if (request.styleStrategy & QFont::PreferAntialias) {
    802             if (QSysInfo::WindowsVersion >= QSysInfo::WV_XP)
    803                 qual = 5; // == CLEARTYPE_QUALITY;
    804             else
     710            if (QSysInfo::WindowsVersion >= QSysInfo::WV_XP) {
     711                qual = CLEARTYPE_QUALITY;
     712                preferClearTypeAA = true;
     713            } else {
    805714                qual = ANTIALIASED_QUALITY;
     715            }
    806716        } else if (request.styleStrategy & QFont::NoAntialias) {
    807717            qual = NONANTIALIASED_QUALITY;
     
    825735            fam = QLatin1String("Courier New");
    826736
    827         QT_WA({
    828             memcpy(lf.lfFaceName, fam.utf16(), sizeof(TCHAR)*qMin(fam.length()+1,32));  // 32 = Windows hard-coded
    829             hfont = CreateFontIndirect(&lf);
    830         } , {
    831             // LOGFONTA and LOGFONTW are binary compatible
    832             QByteArray lname = fam.toLocal8Bit();
    833             memcpy(lf.lfFaceName,lname.data(),
    834                 qMin(lname.length()+1,32));  // 32 = Windows hard-coded
    835             hfont = CreateFontIndirectA((LOGFONTA*)&lf);
    836         });
     737        memcpy(lf.lfFaceName, fam.utf16(), sizeof(wchar_t) * qMin(fam.length() + 1, 32));  // 32 = Windows hard-coded
     738        hfont = CreateFontIndirect(&lf);
    837739        if (!hfont)
    838740            qErrnoWarning("QFontEngine::loadEngine: CreateFontIndirect failed");
     
    843745        BOOL res;
    844746        HGDIOBJ oldObj = SelectObject(hdc, hfont);
    845         QT_WA({
    846             TEXTMETRICW tm;
    847             res = GetTextMetricsW(hdc, &tm);
    848             avWidth = tm.tmAveCharWidth;
    849             ttf = tm.tmPitchAndFamily & TMPF_TRUETYPE;
    850         } , {
    851             TEXTMETRICA tm;
    852             res = GetTextMetricsA(hdc, &tm);
    853             avWidth = tm.tmAveCharWidth;
    854             ttf = tm.tmPitchAndFamily & TMPF_TRUETYPE;
    855         });
     747
     748        TEXTMETRIC tm;
     749        res = GetTextMetrics(hdc, &tm);
     750        avWidth = tm.tmAveCharWidth;
     751        ttf = tm.tmPitchAndFamily & TMPF_TRUETYPE;
     752
    856753        SelectObject(hdc, oldObj);
    857754
     
    861758                qErrnoWarning("QFontEngine::loadEngine: GetTextMetrics failed");
    862759            lf.lfWidth = avWidth * request.stretch/100;
    863             QT_WA({
    864                 hfont = CreateFontIndirect(&lf);
    865             } , {
    866                 hfont = CreateFontIndirectA((LOGFONTA*)&lf);
    867             });
     760            hfont = CreateFontIndirect(&lf);
    868761            if (!hfont)
    869762                qErrnoWarning("QFontEngine::loadEngine: CreateFontIndirect with stretch failed");
    870763        }
    871764
    872 #ifndef Q_OS_WINCE
     765#ifndef Q_WS_WINCE
    873766        if (hfont == 0) {
    874767            hfont = (HFONT)GetStockObject(ANSI_VAR_FONT);
     
    884777    }
    885778    QFontEngineWin *few = new QFontEngineWin(font_name, hfont, stockFont, lf);
     779
     780    if (preferClearTypeAA)
     781        few->glyphFormat = QFontEngineGlyphCache::Raster_RGBMask;
    886782
    887783    // Also check for OpenType tables when using complex scripts
     
    964860    QStringList family_list = familyList(req);
    965861
    966     if(QSysInfo::WindowsVersion & QSysInfo::WV_DOS_based && req.family.toLower() == QLatin1String("ms sans serif")) {
    967         // small hack for Dos based machines to get the right font for non
    968         // latin text when using the default font.
    969         family_list << QLatin1String("Arial");
    970     }
    971 
    972862    const char *stylehint = styleHint(d->request);
    973863    if (stylehint)
     
    1011901}
    1012902
    1013 
    1014903void QFontDatabase::load(const QFontPrivate *d, int script)
    1015904{
     
    1022911    QFontDef req = d->request;
    1023912    if (req.pixelSize <= 0)
    1024         req.pixelSize = qMax(1, qRound(req.pointSize * d->dpi / 72.));
    1025     req.pointSize = 0;
     913        req.pixelSize = qreal((req.pointSize * d->dpi) / 72.);
     914    if (req.pixelSize < 1)
     915        req.pixelSize = 1;
    1026916    if (req.weight == 0)
    1027917        req.weight = QFont::Normal;
     
    1040930
    1041931    // set it to the actual pointsize, so QFontInfo will do the right thing
    1042     req.pointSize = req.pixelSize*72./d->dpi;
     932    if (req.pointSize < 0)
     933        req.pointSize = req.pixelSize*72./d->dpi;
    1043934
    1044935    if (!fe) {
     
    11351026            signature.fsUsb[2] = qFromBigEndian<quint32>(table + 50);
    11361027            signature.fsUsb[3] = qFromBigEndian<quint32>(table + 54);
    1137    
     1028
    11381029            signature.fsCsb[0] = qFromBigEndian<quint32>(table + 78);
    11391030            signature.fsCsb[1] = qFromBigEndian<quint32>(table + 82);
     1031        } else {
     1032            memset(&signature, 0, sizeof(signature));
    11401033        }
    11411034        appFont->signatures << signature;
     
    11601053
    11611054        {
    1162 #ifdef  QT_NO_TEMPORARYFILE
    1163            TCHAR lpBuffer[MAX_PATH];
     1055#ifdef QT_NO_TEMPORARYFILE
     1056           wchar_t lpBuffer[MAX_PATH];
    11641057           GetTempPath(MAX_PATH, lpBuffer);
    1165            QString s = QString::fromUtf16((const ushort *) lpBuffer);
     1058           QString s = QString::fromWCharArray(lpBuffer);
    11661059           QFile tempfile(s + QLatin1String("/font") + QString::number(GetTickCount()) + QLatin1String(".ttf"));
    11671060           if (!tempfile.open(QIODevice::ReadWrite))
     
    11691062            QTemporaryFile tempfile(QLatin1String("XXXXXXXX.ttf"));
    11701063            if (!tempfile.open())
    1171 #endif
     1064#endif // QT_NO_TEMPORARYFILE
    11721065                return;
    11731066            if (tempfile.write(fnt->data) == -1)
    11741067                return;
    11751068
    1176 #ifndef  QT_NO_TEMPORARYFILE
     1069#ifndef QT_NO_TEMPORARYFILE
    11771070            tempfile.setAutoRemove(false);
    11781071#endif
     
    11861079#else
    11871080        DWORD dummy = 0;
    1188         HANDLE handle = ptrAddFontMemResourceEx((void *)fnt->data.constData(),
    1189                                     fnt->data.size(),
    1190                                     0,
    1191                                     &dummy);
     1081        HANDLE handle = ptrAddFontMemResourceEx((void *)fnt->data.constData(), fnt->data.size(), 0,
     1082                                                &dummy);
    11921083        if (handle == 0)
    11931084            return;
    1194 #endif
     1085#endif // Q_OS_WINCE
    11951086
    11961087        fnt->handle = handle;
     
    12141105        PtrAddFontResourceExW ptrAddFontResourceExW = (PtrAddFontResourceExW)QLibrary::resolve(QLatin1String("gdi32"),
    12151106                                                                                               "AddFontResourceExW");
    1216         if (!ptrAddFontResourceExW)
     1107        if (!ptrAddFontResourceExW
     1108            || ptrAddFontResourceExW((wchar_t*)fnt->fileName.utf16(), FR_PRIVATE, 0) == 0)
    12171109            return;
    1218 
    1219         if (ptrAddFontResourceExW((LPCWSTR)fnt->fileName.utf16(), FR_PRIVATE, 0) == 0)
    1220             return;
    1221 #endif
     1110#endif // Q_OS_WINCE
    12221111
    12231112        fnt->memoryFont = false;
     
    12451134        PtrRemoveFontMemResourceEx ptrRemoveFontMemResourceEx = (PtrRemoveFontMemResourceEx)QLibrary::resolve(QLatin1String("gdi32"),
    12461135                                                                                                              "RemoveFontMemResourceEx");
    1247         if (!ptrRemoveFontMemResourceEx)
     1136        if (!ptrRemoveFontMemResourceEx
     1137            || !ptrRemoveFontMemResourceEx(font.handle))
    12481138            return false;
    1249 
    1250         if (!ptrRemoveFontMemResourceEx(font.handle))
    1251             return false;
    1252 #endif
     1139#endif // Q_OS_WINCE
    12531140    } else {
    12541141#ifdef Q_OS_WINCE
     
    12581145        PtrRemoveFontResourceExW ptrRemoveFontResourceExW = (PtrRemoveFontResourceExW)QLibrary::resolve(QLatin1String("gdi32"),
    12591146                                                                                                        "RemoveFontResourceExW");
    1260         if (!ptrRemoveFontResourceExW)
     1147        if (!ptrRemoveFontResourceExW
     1148            || !ptrRemoveFontResourceExW((LPCWSTR)font.fileName.utf16(), FR_PRIVATE, 0))
    12611149            return false;
    1262 
    1263         if (!ptrRemoveFontResourceExW((LPCWSTR)font.fileName.utf16(), FR_PRIVATE, 0))
    1264             return false;
    1265 #endif
     1150#endif // Q_OS_WINCE
    12661151    }
    12671152
  • trunk/src/gui/text/qfontdatabase_x11.cpp

    r2 r561  
    22**
    33** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
    4 ** Contact: Qt Software Information (qt-info@nokia.com)
     4** All rights reserved.
     5** Contact: Nokia Corporation (qt-info@nokia.com)
    56**
    67** This file is part of the QtGui module of the Qt Toolkit.
     
    2122** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    2223**
    23 ** In addition, as a special exception, Nokia gives you certain
    24 ** additional rights. These rights are described in the Nokia Qt LGPL
    25 ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
    26 ** package.
     24** In addition, as a special exception, Nokia gives you certain additional
     25** rights.  These rights are described in the Nokia Qt LGPL Exception
     26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
    2727**
    2828** GNU General Public License Usage
     
    3434** met: http://www.gnu.org/copyleft/gpl.html.
    3535**
    36 ** If you are unsure which license is appropriate for your use, please
    37 ** contact the sales department at qt-sales@nokia.com.
     36** If you have questions regarding the use of this file, please contact
     37** Nokia at qt-info@nokia.com.
    3838** $QT_END_LICENSE$
    3939**
     
    5252#include <qtemporaryfile.h>
    5353#include <qabstractfileengine.h>
     54#include <qmath.h>
    5455
    5556#include <ctype.h>
     
    155156      0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
    156157      0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
    157       0 },
     158      0, 0 },
    158159    // iso8859-2
    159160    { 0, 1, 0, 0, 0, 0, 0, 0, 0, 0,
    160161      0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
    161162      0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
    162       0 },
     163      0, 0 },
    163164    // iso8859-3
    164165    { 0, 1, 0, 0, 0, 0, 0, 0, 0, 0,
    165166      0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
    166167      0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
    167       0 },
     168      0, 0 },
    168169    // iso8859-4
    169170    { 0, 1, 0, 0, 0, 0, 0, 0, 0, 0,
    170171      0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
    171172      0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
    172       0 },
     173      0, 0 },
    173174    // iso8859-9
    174175    { 0, 1, 0, 0, 0, 0, 0, 0, 0, 0,
    175176      0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
    176177      0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
    177       0 },
     178      0, 0 },
    178179    // iso8859-10
    179180    { 0, 1, 0, 0, 0, 0, 0, 0, 0, 0,
    180181      0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
    181182      0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
    182       0 },
     183      0, 0 },
    183184    // iso8859-13
    184185    { 0, 1, 0, 0, 0, 0, 0, 0, 0, 0,
    185186      0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
    186187      0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
    187       0 },
     188      0, 0 },
    188189    // iso8859-14
    189190    { 0, 1, 0, 0, 0, 0, 0, 0, 0, 0,
    190191      0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
    191192      0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
    192       0 },
     193      0, 0 },
    193194    // iso8859-15
    194195    { 0, 1, 0, 0, 0, 0, 0, 0, 0, 0,
    195196      0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
    196197      0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
    197       0 },
     198      0, 0 },
    198199    // hp-roman8
    199200    { 0, 1, 0, 0, 0, 0, 0, 0, 0, 0,
    200201      0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
    201202      0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
    202       0 },
     203      0, 0 },
    203204    // iso8859-5
    204205    { 0, 0, 0, 1, 0, 0, 0, 0, 0, 0,
    205206      0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
    206207      0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
    207       0 },
     208      0, 0 },
    208209    // *-cp1251
    209210    { 0, 0, 0, 1, 0, 0, 0, 0, 0, 0,
    210211      0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
    211212      0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
    212       0 },
     213      0, 0 },
    213214    // koi8-ru
    214215    { 0, 0, 0, 1, 0, 0, 0, 0, 0, 0,
    215216      0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
    216217      0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
    217       0 },
     218      0, 0 },
    218219    // koi8-u
    219220    { 0, 0, 0, 1, 0, 0, 0, 0, 0, 0,
    220221      0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
    221222      0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
    222       0 },
     223      0, 0 },
    223224    // koi8-r
    224225    { 0, 0, 0, 1, 0, 0, 0, 0, 0, 0,
    225226      0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
    226227      0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
    227       0 },
     228      0, 0 },
    228229    // iso8859-7
    229230    { 0, 0, 1, 0, 0, 0, 0, 0, 0, 0,
    230231      0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
    231232      0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
    232       0 },
     233      0, 0 },
    233234    // iso8859-8
    234235    { 0, 0, 0, 0, 0, 1, 0, 0, 0, 0,
    235236      0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
    236237      0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
    237       0 },
     238      0, 0 },
    238239    // gb18030-0
    239240    { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
    240241      0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
    241242      0, 0, 0, 0, 0, 1, 0, 0, 0, 0,
    242       0 },
     243      0, 0 },
    243244    // gb18030.2000-0
    244245    { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
    245246      0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
    246247      0, 0, 0, 0, 0, 1, 0, 0, 0, 0,
    247       0 },
     248      0, 0 },
    248249    // gbk-0
    249250    { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
    250251      0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
    251252      0, 0, 0, 0, 0, 1, 0, 0, 0, 0,
    252       0 },
     253      0, 0 },
    253254    // gb2312.*-0
    254255    { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
    255256      0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
    256257      0, 0, 0, 0, 0, 1, 0, 0, 0, 0,
    257       0 },
     258      0, 0 },
    258259    // jisx0201*-0
    259260    { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
    260261      0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
    261262      0, 0, 0, 0, 0, 0, 0, 1, 0, 0,
    262       0 },
     263      0, 0 },
    263264    // jisx0208*-0
    264265    { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
    265266      0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
    266267      0, 0, 0, 0, 0, 0, 0, 1, 0, 0,
    267       0 },
     268      0, 0 },
    268269    // ksc5601*-*
    269270    { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
    270271      0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
    271272      0, 0, 0, 0, 0, 0, 0, 0, 1, 0,
    272       0 },
     273      0, 0 },
    273274    // big5hkscs-0
    274275    { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
    275276      0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
    276277      0, 0, 0, 0, 0, 0, 1, 0, 0, 0,
    277       0 },
     278      0, 0 },
    278279    // hkscs-1
    279280    { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
    280281      0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
    281282      0, 0, 0, 0, 0, 0, 1, 0, 0, 0,
    282       0 },
     283      0, 0 },
    283284    // big5*-*
    284285    { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
    285286      0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
    286287      0, 0, 0, 0, 0, 0, 1, 0, 0, 0,
    287       0 },
     288      0, 0 },
    288289    // tscii-*
    289290    { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
    290291      0, 0, 0, 0, 1, 0, 0, 0, 0, 0,
    291292      0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
    292       0 },
     293      0, 0 },
    293294    // tis620*-*
    294295    { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
    295296      0, 0, 0, 0, 0, 0, 0, 0, 0, 1,
    296297      0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
    297       0 },
     298      0, 0 },
    298299    // iso8859-11
    299300    { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
    300301      0, 0, 0, 0, 0, 0, 0, 0, 0, 1,
    301302      0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
    302       0 },
     303      0, 0 },
    303304    // mulelao-1
    304305    { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
    305306      0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
    306307      1, 0, 0, 0, 0, 0, 0, 0, 0, 0,
    307       0 },
     308      0, 0 },
    308309    // ethiopic-unicode
    309310    { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
    310311      0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
    311312      0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
    312       0 },
     313      0, 0 },
    313314    // iso10646-1
    314315    { 0, 1, 1, 1, 1, 1, 1, 0, 0, 0,
    315316      0, 0, 0, 0, 0, 0, 0, 0, 0, 1,
    316317      1, 1, 0, 1, 0, 1, 1, 0, 0, 0,
    317       0 },
     318      0, 0 },
    318319    // unicode-*
    319320    { 0, 1, 1, 1, 1, 1, 1, 0, 0, 0,
    320321      0, 0, 0, 0, 0, 0, 0, 0, 0, 1,
    321322      1, 1, 0, 1, 0, 1, 1, 0, 0, 0,
    322       0 },
     323      0, 0 },
    323324    // *-symbol
    324325    { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
    325326      0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
    326327      0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
    327       1 },
     328      1, 0 },
    328329    // *-fontspecific
    329330    { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
    330331      0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
    331332      0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
    332       1 },
     333      1, 0 },
    333334    // fontspecific-*
    334335    { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
    335336      0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
    336337      0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
    337       1 }
     338      1, 0 }
    338339
    339340};
     
    393394    if (id != -1) return xlfd_encoding[id].mib;
    394395    return 0;
    395 };
     396}
    396397
    397398int qt_encoding_id_for_mib(int mib)
     
    495496  Description).
    496497
    497   Returns true if the the given xlfd is valid.
     498  Returns true if the given xlfd is valid.
    498499*/
    499500bool qt_fillFontDef(const QByteArray &xlfd, QFontDef *fd, int dpi, QtFontDesc *desc)
     
    510511    fd->family = QString::fromLatin1(tokens[Family]);
    511512    QString foundry = QString::fromLatin1(tokens[Foundry]);
    512     if (! foundry.isEmpty() && foundry != QString::fromLatin1("*") && (!desc || desc->family->count > 1))
     513    if (! foundry.isEmpty() && foundry != QLatin1String("*") && (!desc || desc->family->count > 1))
    513514        fd->family +=
    514             QString::fromLatin1(" [") + foundry + QString::fromLatin1("]");
     515            QLatin1String(" [") + foundry + QLatin1Char(']');
    515516
    516517    if (qstrlen(tokens[AddStyle]) > 0)
     
    753754            dpi = QX11Info::appDpiY();
    754755        else
    755             dpi = 96; // ####
     756            dpi = qt_defaultDpiY();
    756757    }
    757758
    758759    double size;
    759760    if (FcPatternGetDouble(pattern, FC_PIXEL_SIZE, 0, &size) == FcResultMatch)
    760         fontDef.pixelSize = qRound(size);
     761        fontDef.pixelSize = size;
    761762    else
    762763        fontDef.pixelSize = 12;
     
    835836    "", // Ogham
    836837    "", // Runic
    837     "km" // Khmer
     838    "km", // Khmer
     839    "" // N'Ko
    838840};
    839841enum { SpecialLanguageCount = sizeof(specialLanguages) / sizeof(const char *) };
     
    866868    0x1681, // Ogham
    867869    0x16a0, // Runic
    868     0  // Khmer
     870    0,  // Khmer
     871    0x7ca // N'Ko
    869872};
    870873enum { SpecialCharCount = sizeof(specialChars) / sizeof(ushort) };
     
    905908    0, // Symbol
    906909    0, // Ogham
    907     0 // Runic
     910    0, // Runic
     911    0 // N'Ko
    908912};
    909913enum { LanguageCount = sizeof(languageForWritingSystem) / sizeof(const char *) };
     
    944948    0, // Symbol
    945949    0x1681, // Ogham
    946     0x16a0 // Runic
     950    0x16a0, // Runic
     951    0x7ca // N'Ko
    947952};
    948953enum { SampleCharCount = sizeof(sampleCharForWritingSystem) / sizeof(ushort) };
     
    984989    0, // Symbol
    985990    0, // Ogham
    986     0 // Runic
     991    0, // Runic
     992    "nko " // N'Ko
    987993};
    988994enum { OpenTypeCount = sizeof(openType) / sizeof(const char *) };
     
    12051211static void initializeDb();
    12061212
    1207 static void load(const QString &family = QString(), int script = -1)
    1208 {
    1209     if (X11->has_fontconfig) {
     1213static void load(const QString &family = QString(), int script = -1, bool forceXLFD = false)
     1214{
     1215    if (X11->has_fontconfig && !forceXLFD) {
    12101216        initializeDb();
    12111217        return;
     
    14561462    FcPatternAddInteger(pattern, FC_SLANT, slant_value);
    14571463
    1458     double size_value = qMax(1, request.pixelSize);
     1464    double size_value = qMax(qreal(1.), request.pixelSize);
    14591465    FcPatternAddDouble(pattern, FC_PIXEL_SIZE, size_value);
    14601466
     
    14721478    }
    14731479
    1474     if (script != QUnicodeTables::Common) {
     1480    if (script != QUnicodeTables::Common && *specialLanguages[script] != '\0') {
    14751481        Q_ASSERT(script < QUnicodeTables::ScriptCount);
    14761482        FcLangSet *ls = FcLangSetCreate();
     
    16151621            if (!FcCharSetHasChar(cs, specialChars[script]))
    16161622                goto done;
    1617         } else {
     1623        } else if (*specialLanguages[script] != '\0'){
    16181624            FcLangSet *langSet = 0;
    16191625            if (FcPatternGetLangSet(match, FC_LANG, 0, &langSet) != FcResultMatch)
     
    17851791        QT_PREPEND_NAMESPACE(parseFontName)(families_and_foundries.at(i), foundry, family);
    17861792        FM_DEBUG("loadXlfd: >>>>>>>>>>>>>>trying to match '%s' encoding=%d", family.toLatin1().data(), force_encoding_id);
    1787         QT_PREPEND_NAMESPACE(match)(script, request, family, foundry, force_encoding_id, &desc);
     1793        QT_PREPEND_NAMESPACE(match)(script, request, family, foundry, force_encoding_id, &desc, QList<int>(), true);
    17881794        if (desc.family)
    17891795            break;
     
    18031809            QByteArray xlfd("-");
    18041810            xlfd += desc.foundry->name.isEmpty() ? QByteArray("*") : desc.foundry->name.toLatin1();
    1805             xlfd += "-";
     1811            xlfd += '-';
    18061812            xlfd += desc.family->name.isEmpty() ? QByteArray("*") : desc.family->name.toLatin1();
    1807             xlfd += "-";
     1813            xlfd += '-';
    18081814            xlfd += desc.style->weightName ? desc.style->weightName : "*";
    1809             xlfd += "-";
     1815            xlfd += '-';
    18101816            xlfd += (desc.style->key.style == QFont::StyleItalic
    1811                      ? "i"
    1812                      : (desc.style->key.style == QFont::StyleOblique ? "o" : "r"));
    1813             xlfd += "-";
     1817                     ? 'i'
     1818                     : (desc.style->key.style == QFont::StyleOblique ? 'o' : 'r'));
     1819            xlfd += '-';
    18141820            xlfd += desc.style->setwidthName ? desc.style->setwidthName : "*";
    18151821            // ### handle add-style
    18161822            xlfd += "-*-";
    18171823            xlfd += QByteArray::number(px);
    1818             xlfd += "-";
     1824            xlfd += '-';
    18191825            xlfd += QByteArray::number(desc.encoding->xpoint);
    1820             xlfd += "-";
     1826            xlfd += '-';
    18211827            xlfd += QByteArray::number(desc.encoding->xres);
    1822             xlfd += "-";
     1828            xlfd += '-';
    18231829            xlfd += QByteArray::number(desc.encoding->yres);
    1824             xlfd += "-";
     1830            xlfd += '-';
    18251831            xlfd += desc.encoding->pitch;
    1826             xlfd += "-";
     1832            xlfd += '-';
    18271833            xlfd += QByteArray::number(desc.encoding->avgwidth);
    1828             xlfd += "-";
     1834            xlfd += '-';
    18291835            xlfd += xlfd_for_id(desc.encoding->encoding);
    18301836
     
    18481854    } else {
    18491855        QList<int> encodings;
    1850         if (desc.encoding)
    1851             encodings.append(int(desc.encoding->encoding));
     1856        if (desc.encoding) {
     1857            if (desc.encoding->encoding >= 0)
     1858                encodings.append(int(desc.encoding->encoding));
     1859        }
    18521860
    18531861        if (desc.size) {
     
    18551863            for (int i = 0; i < desc.size->count; ++i) {
    18561864                QtFontEncoding *e = desc.size->encodings + i;
    1857                 if (e == desc.encoding)
    1858                     continue;
     1865                if (e == desc.encoding || e->encoding < 0)
     1866                    continue;               
    18591867                encodings.append(int(e->encoding));
    18601868            }
     
    18631871        const XlfdEncoding *enc = xlfd_encoding;
    18641872        for (; enc->name; ++enc) {
    1865             if (!encodings.contains(enc->id))
     1873            if (!encodings.contains(enc->id) && enc->id >= 0) {
    18661874                encodings.append(enc->id);
     1875            }
    18671876        }
    18681877
     
    18911900    QFontDef req = d->request;
    18921901    if (req.pixelSize <= 0)
    1893         req.pixelSize = qRound(qt_pixelSize(req.pointSize, d->dpi));
    1894     req.pointSize = 0;
     1902        req.pixelSize = floor(qt_pixelSize(req.pointSize, d->dpi) * 100 + 0.5) / 100;
     1903    if (req.pixelSize < 1)
     1904        req.pixelSize = 1;
    18951905    if (req.weight == 0)
    18961906        req.weight = QFont::Normal;
     
    19071917
    19081918    // set it to the actual pointsize, so QFontInfo will do the right thing
    1909     req.pointSize = qt_pointSize(req.pixelSize, d->dpi);
     1919    if (req.pointSize < 0)
     1920        req.pointSize = qt_pointSize(req.pixelSize, d->dpi);
     1921
    19101922
    19111923    QFontEngine *fe = QFontCache::instance()->findEngine(key);
     
    19261938        } else if (X11->has_fontconfig) {
    19271939            fe = loadFc(d, script, req);
     1940
     1941            if (fe != 0 && fe->fontDef.pixelSize != req.pixelSize) {
     1942                delete fe;
     1943                fe = loadXlfd(d->screen, script, req);
     1944            }
     1945
     1946
    19281947#endif
    19291948        } else if (mainThread) {
  • trunk/src/gui/text/qfontengine.cpp

    r125 r561  
    22**
    33** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
    4 ** Contact: Qt Software Information (qt-info@nokia.com)
     4** All rights reserved.
     5** Contact: Nokia Corporation (qt-info@nokia.com)
    56**
    67** This file is part of the QtGui module of the Qt Toolkit.
     
    2122** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    2223**
    23 ** In addition, as a special exception, Nokia gives you certain
    24 ** additional rights. These rights are described in the Nokia Qt LGPL
    25 ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
    26 ** package.
     24** In addition, as a special exception, Nokia gives you certain additional
     25** rights.  These rights are described in the Nokia Qt LGPL Exception
     26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
    2727**
    2828** GNU General Public License Usage
     
    3434** met: http://www.gnu.org/copyleft/gpl.html.
    3535**
    36 ** If you are unsure which license is appropriate for your use, please
    37 ** contact the sales department at qt-sales@nokia.com.
     36** If you have questions regarding the use of this file, please contact
     37** Nokia at qt-info@nokia.com.
    3838** $QT_END_LICENSE$
    3939**
     
    7171}
    7272
    73 
    74 
    75 QFontEngineGlyphCache::~QFontEngineGlyphCache()
    76 {
    77 }
    78 
    7973// Harfbuzz helper functions
    8074
     
    192186QFontEngine::~QFontEngine()
    193187{
    194     for (GlyphPointerHash::iterator it = m_glyphPointerHash.begin(), end = m_glyphPointerHash.end();
    195          it != end; ++it) {
    196         for (QList<QFontEngineGlyphCache*>::iterator it2 = it.value().begin(), end2 = it.value().end();
    197             it2 != end2; ++it2)
    198                 delete *it2;
    199     }
    200     m_glyphPointerHash.clear();
    201     for (GlyphIntHash::iterator it = m_glyphIntHash.begin(), end = m_glyphIntHash.end();
    202          it != end; ++it) {
    203         for (QList<QFontEngineGlyphCache*>::iterator it2 = it.value().begin(), end2 = it.value().end();
    204             it2 != end2; ++it2)
    205                 delete *it2;
    206     }
    207     m_glyphIntHash.clear();
     188    for (QLinkedList<GlyphCacheEntry>::const_iterator it = m_glyphCaches.constBegin(),
     189            end = m_glyphCaches.constEnd(); it != end; ++it) {
     190        delete it->cache;
     191    }
     192    m_glyphCaches.clear();
    208193    qHBFreeFace(hbFace);
    209194}
     
    241226HB_Face QFontEngine::harfbuzzFace() const
    242227{
    243     if (!hbFace)
     228    if (!hbFace) {
    244229        hbFace = qHBNewFace(const_cast<QFontEngine *>(this), hb_getSFntTable);
     230        Q_CHECK_PTR(hbFace);
     231    }
    245232    return hbFace;
    246233}
     
    429416    QVarLengthArray<QFixedPoint> positions;
    430417    QVarLengthArray<glyph_t> positioned_glyphs;
    431     QTransform matrix;
    432     matrix.translate(x, y);
     418    QTransform matrix = QTransform::fromTranslate(x, y);
    433419    getGlyphPositions(glyphs, matrix, flags, positioned_glyphs, positions);
    434420    addGlyphsToPath(positioned_glyphs.data(), positions.data(), positioned_glyphs.size(), path, flags);
     
    625611}
    626612
     613QImage QFontEngine::alphaMapForGlyph(glyph_t glyph)
     614{
     615    glyph_metrics_t gm = boundingBox(glyph);
     616    int glyph_x = qFloor(gm.x.toReal());
     617    int glyph_y = qFloor(gm.y.toReal());
     618    int glyph_width = qCeil((gm.x + gm.width).toReal()) -  glyph_x;
     619    int glyph_height = qCeil((gm.y + gm.height).toReal()) - glyph_y;
     620
     621    if (glyph_width <= 0 || glyph_height <= 0)
     622        return QImage();
     623    QFixedPoint pt;
     624    pt.x = 0;
     625    pt.y = -glyph_y; // the baseline
     626    QPainterPath path;
     627    QImage im(glyph_width + qAbs(glyph_x) + 4, glyph_height, QImage::Format_ARGB32_Premultiplied);
     628    im.fill(Qt::transparent);
     629    QPainter p(&im);
     630    p.setRenderHint(QPainter::Antialiasing);
     631    addGlyphsToPath(&glyph, &pt, 1, &path, 0);
     632    p.setPen(Qt::NoPen);
     633    p.setBrush(Qt::black);
     634    p.drawPath(path);
     635    p.end();
     636
     637    QImage indexed(im.width(), im.height(), QImage::Format_Indexed8);
     638    QVector<QRgb> colors(256);
     639    for (int i=0; i<256; ++i)
     640        colors[i] = qRgba(0, 0, 0, i);
     641    indexed.setColorTable(colors);
     642
     643    for (int y=0; y<im.height(); ++y) {
     644        uchar *dst = (uchar *) indexed.scanLine(y);
     645        uint *src = (uint *) im.scanLine(y);
     646        for (int x=0; x<im.width(); ++x)
     647            dst[x] = qAlpha(src[x]);
     648    }
     649
     650    return indexed;
     651}
    627652
    628653void QFontEngine::removeGlyphFromCache(glyph_t)
     
    678703}
    679704
    680 void QFontEngine::expireGlyphCache()
    681 {
    682     if (m_glyphCacheQueue.count() > 10) { // hold only 10 caches in memory.
    683         QFontEngineGlyphCache *old = m_glyphCacheQueue.takeFirst();
    684         // remove the value from either of our hashes
    685         for (GlyphPointerHash::iterator i = m_glyphPointerHash.begin(); i != m_glyphPointerHash.end(); ++i) {
    686             QList<QFontEngineGlyphCache *> list = i.value();
    687             if (list.removeAll(old)) {
    688                 if (list.isEmpty())
    689                     m_glyphPointerHash.remove(i.key());
    690                 else
    691                     m_glyphPointerHash.insert(i.key(), list);
    692                 break;
    693             }
    694         }
    695         for (GlyphIntHash::iterator i = m_glyphIntHash.begin(); i != m_glyphIntHash.end(); ++i) {
    696             QList<QFontEngineGlyphCache *> list = i.value();
    697             if (list.removeAll(old)) {
    698                 if (list.isEmpty())
    699                     m_glyphIntHash.remove(i.key());
    700                 else
    701                     m_glyphIntHash.insert(i.key(), list);
    702                 break;
    703             }
    704         }
    705         delete old;
    706     }
    707 }
    708 
    709705void QFontEngine::setGlyphCache(void *key, QFontEngineGlyphCache *data)
    710706{
    711707    Q_ASSERT(data);
    712     QList<QFontEngineGlyphCache*> items = m_glyphPointerHash.value(key);
    713 
    714     for (QList<QFontEngineGlyphCache*>::iterator it = items.begin(), end = items.end(); it != end; ++it) {
    715         QFontEngineGlyphCache *c = *it;
    716         if (qtransform_equals_no_translate(c->m_transform, data->m_transform)) {
    717             if (c == data)
    718                 return;
    719             items.removeAll(c);
    720             delete c;
    721             break;
    722         }
    723     }
    724     items.append(data);
    725     m_glyphPointerHash.insert(key, items);
    726 
    727     m_glyphCacheQueue.append(data);
    728     expireGlyphCache();
    729 }
    730 
    731 void QFontEngine::setGlyphCache(QFontEngineGlyphCache::Type key, QFontEngineGlyphCache *data)
    732 {
    733     Q_ASSERT(data);
    734     QList<QFontEngineGlyphCache*> items = m_glyphIntHash.value(key);
    735 
    736     for (QList<QFontEngineGlyphCache*>::iterator it = items.begin(), end = items.end(); it != end; ++it) {
    737         QFontEngineGlyphCache *c = *it;
    738         if (qtransform_equals_no_translate(c->m_transform, data->m_transform)) {
    739             if (c == data)
    740                 return;
    741             items.removeAll(c);
    742             delete c;
    743             break;
    744         }
    745     }
    746     items.append(data);
    747     m_glyphIntHash.insert(key, items);
    748 
    749     m_glyphCacheQueue.append(data);
    750     expireGlyphCache();
    751 }
    752 
    753 QFontEngineGlyphCache *QFontEngine::glyphCache(void *key, const QTransform &transform) const
    754 {
    755     QList<QFontEngineGlyphCache*> items = m_glyphPointerHash.value(key);
    756 
    757     for (QList<QFontEngineGlyphCache*>::iterator it = items.begin(), end = items.end(); it != end; ++it) {
    758         QFontEngineGlyphCache *c = *it;
    759         if (qtransform_equals_no_translate(c->m_transform, transform)) {
    760             m_glyphCacheQueue.removeAll(c); // last used, move it up
    761             m_glyphCacheQueue.append(c);
     708
     709    GlyphCacheEntry entry = { key, data };
     710    if (m_glyphCaches.contains(entry))
     711        return;
     712
     713    // Limit the glyph caches to 4. This covers all 90 degree rotations and limits
     714    // memory use when there is continous or random rotation
     715    if (m_glyphCaches.size() == 4)
     716        delete m_glyphCaches.takeLast().cache;
     717
     718    m_glyphCaches.push_front(entry);
     719
     720}
     721
     722QFontEngineGlyphCache *QFontEngine::glyphCache(void *key, QFontEngineGlyphCache::Type type, const QTransform &transform) const
     723{
     724    for (QLinkedList<GlyphCacheEntry>::const_iterator it = m_glyphCaches.constBegin(), end = m_glyphCaches.constEnd(); it != end; ++it) {
     725        QFontEngineGlyphCache *c = it->cache;
     726        if (key == it->context
     727            && type == c->cacheType()
     728            && qtransform_equals_no_translate(c->m_transform, transform)) {
    762729            return c;
    763730        }
     
    766733}
    767734
    768 QFontEngineGlyphCache *QFontEngine::glyphCache(QFontEngineGlyphCache::Type key, const QTransform &transform) const
    769 {
    770     QList<QFontEngineGlyphCache*> items = m_glyphIntHash.value(key);
    771 
    772     for (QList<QFontEngineGlyphCache*>::iterator it = items.begin(), end = items.end(); it != end; ++it) {
    773         QFontEngineGlyphCache *c = *it;
    774         if (qtransform_equals_no_translate(c->m_transform, transform)) {
    775             m_glyphCacheQueue.removeAll(c); // last used, move it up
    776             m_glyphCacheQueue.append(c);
    777             return c;
    778         }
    779     }
    780     return 0;
    781 }
    782 
    783 #if defined(Q_WS_WIN) || defined(Q_WS_PM) || defined(Q_WS_X11) || defined(Q_WS_QWS)
     735#if defined(Q_WS_WIN) || defined(Q_WS_X11) || defined(Q_WS_QWS) || defined(Q_OS_SYMBIAN) || defined(Q_WS_PM) || defined(Q_WS_PM)
    784736static inline QFixed kerning(int left, int right, const QFontEngine::KernPair *pairs, int numPairs)
    785737{
     
    877829    qSort(kerning_pairs);
    878830//    for (int i = 0; i < kerning_pairs.count(); ++i)
    879 //        qDebug() << "i" << i << "left_right" << hex << kerning_pairs.at(i).left_right;
     831//        qDebug() << 'i' << i << "left_right" << hex << kerning_pairs.at(i).left_right;
    880832}
    881833
     
    911863        return 0;
    912864
     865    enum {
     866        Invalid,
     867        Symbol,
     868        AppleRoman,
     869        Unicode11,
     870        Unicode,
     871        MicrosoftUnicode,
     872        MicrosoftUnicodeExtended
     873    };
     874
     875    int symbolTable = -1;
    913876    int tableToUse = -1;
    914     int score = 0;
     877    int score = Invalid;
    915878    for (int n = 0; n < numTables; ++n) {
    916879        const quint16 platformId = qFromBigEndian<quint16>(maps + 8 * n);
     
    918881        switch (platformId) {
    919882        case 0: // Unicode
    920             if (score < 4 &&
     883            if (score < Unicode &&
    921884                (platformSpecificId == 0 ||
    922885                 platformSpecificId == 2 ||
    923886                 platformSpecificId == 3)) {
    924887                tableToUse = n;
    925                 score = 4;
    926             } else if (score < 3 && platformSpecificId == 1) {
     888                score = Unicode;
     889            } else if (score < Unicode11 && platformSpecificId == 1) {
    927890                tableToUse = n;
    928                 score = 3;
     891                score = Unicode11;
    929892            }
    930893            break;
    931894        case 1: // Apple
    932             if (score < 2 && platformSpecificId == 0) { // Apple Roman
     895            if (score < AppleRoman && platformSpecificId == 0) { // Apple Roman
    933896                tableToUse = n;
    934                 score = 2;
     897                score = AppleRoman;
    935898            }
    936899            break;
     
    938901            switch (platformSpecificId) {
    939902            case 0:
    940                 if (score < 1) {
     903                symbolTable = n;
     904                if (score < Symbol) {
    941905                    tableToUse = n;
    942                     score = 1;
     906                    score = Symbol;
    943907                }
    944908                break;
    945909            case 1:
    946                 if (score < 5) {
     910                if (score < MicrosoftUnicode) {
    947911                    tableToUse = n;
    948                     score = 5;
     912                    score = MicrosoftUnicode;
    949913                }
    950914                break;
    951915            case 0xa:
    952                 if (score < 6) {
     916                if (score < MicrosoftUnicodeExtended) {
    953917                    tableToUse = n;
    954                     score = 6;
     918                    score = MicrosoftUnicodeExtended;
    955919                }
    956920                break;
     
    964928    if(tableToUse < 0)
    965929        return 0;
    966     *isSymbolFont = (score == 1);
     930
     931resolveTable:
     932    *isSymbolFont = (score == Symbol);
    967933
    968934    unsigned int unicode_table = qFromBigEndian<quint32>(maps + 8*tableToUse + 4);
     
    984950        return 0;
    985951    *cmapSize = length;
     952
     953    // To support symbol fonts that contain a unicode table for the symbol area
     954    // we check the cmap tables and fall back to symbol font unless that would
     955    // involve losing information from the unicode table
     956    if (symbolTable > -1 && ((score == Unicode) || (score == Unicode11))) {
     957        const uchar *selectedTable = table + unicode_table;
     958
     959        // Check that none of the latin1 range are in the unicode table
     960        bool unicodeTableHasLatin1 = false;
     961        for (int uc=0x00; uc<0x100; ++uc) {
     962            if (getTrueTypeGlyphIndex(selectedTable, uc) != 0) {
     963                unicodeTableHasLatin1 = true;
     964                break;
     965            }
     966        }
     967
     968        // Check that at least one symbol char is in the unicode table
     969        bool unicodeTableHasSymbols = false;
     970        if (!unicodeTableHasLatin1) {
     971            for (int uc=0xf000; uc<0xf100; ++uc) {
     972                if (getTrueTypeGlyphIndex(selectedTable, uc) != 0) {
     973                    unicodeTableHasSymbols = true;
     974                    break;
     975                }
     976            }
     977        }
     978
     979        // Fall back to symbol table
     980        if (!unicodeTableHasLatin1 && unicodeTableHasSymbols) {
     981            tableToUse = symbolTable;
     982            score = Symbol;
     983            goto resolveTable;
     984        }
     985    }
     986
    986987    return table + unicode_table;
    987988}
     
    10031004        quint16 segCountX2 = qFromBigEndian<quint16>(cmap + 6);
    10041005        const unsigned char *ends = cmap + 14;
    1005         quint16 endIndex = 0;
    10061006        int i = 0;
    1007         for (; i < segCountX2/2 && (endIndex = qFromBigEndian<quint16>(ends + 2*i)) < unicode; i++) {}
     1007        for (; i < segCountX2/2 && qFromBigEndian<quint16>(ends + 2*i) < unicode; i++) {}
    10081008
    10091009        const unsigned char *idx = ends + segCountX2 + 2 + 2*i;
     
    10721072}
    10731073
     1074Q_GLOBAL_STATIC_WITH_INITIALIZER(QVector<QRgb>, qt_grayPalette, {
     1075    x->resize(256);
     1076    QRgb *it = x->data();
     1077    for (int i = 0; i < x->size(); ++i, ++it)
     1078        *it = 0xff000000 | i | (i<<8) | (i<<16);
     1079})
     1080
     1081const QVector<QRgb> &QFontEngine::grayPalette()
     1082{
     1083    return *qt_grayPalette();
     1084}
     1085
    10741086// ------------------------------------------------------------------
    10751087// The box font engine
     
    11191131    QVarLengthArray<QFixedPoint> positions;
    11201132    QVarLengthArray<glyph_t> positioned_glyphs;
    1121     QTransform matrix;
    1122     matrix.translate(x, y - _size);
     1133    QTransform matrix = QTransform::fromTranslate(x, y - _size);
    11231134    getGlyphPositions(glyphs, matrix, flags, positioned_glyphs, positions);
    11241135
     
    11481159    QVarLengthArray<QFixedPoint> positions;
    11491160    QVarLengthArray<glyph_t> glyphs;
    1150     QTransform matrix;
    1151     matrix.translate(x, y - _size);
     1161    QTransform matrix = QTransform::fromTranslate(x, y - _size);
    11521162    ti.fontEngine->getGlyphPositions(ti.glyphs, matrix, ti.flags, glyphs, positions);
    11531163    if (glyphs.size() == 0)
     
    12771287        bool surrogate = (str[i].unicode() >= 0xd800 && str[i].unicode() < 0xdc00 && i < len-1
    12781288                          && str[i+1].unicode() >= 0xdc00 && str[i+1].unicode() < 0xe000);
    1279         if (glyphs->glyphs[glyph_pos] == 0) {
    1280 
     1289
     1290        if (glyphs->glyphs[glyph_pos] == 0 && str[i].category() != QChar::Separator_Line) {
    12811291            QGlyphLayoutInstance tmp = glyphs->instance(glyph_pos);
    12821292            for (int x = 1; x < engines.size(); ++x) {
     
    16081618}
    16091619
    1610 QFontEngine *QFontEngineMulti::engine(int at) const
    1611 {
    1612     Q_ASSERT(at < engines.size());
    1613     return engines.at(at);
    1614 }
    1615 
    16161620QImage QFontEngineMulti::alphaMapForGlyph(glyph_t)
    16171621{
  • trunk/src/gui/text/qfontengine_ft.cpp

    r2 r561  
    22**
    33** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
    4 ** Contact: Qt Software Information (qt-info@nokia.com)
     4** All rights reserved.
     5** Contact: Nokia Corporation (qt-info@nokia.com)
    56**
    67** This file is part of the QtGui module of the Qt Toolkit.
     
    2122** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    2223**
    23 ** In addition, as a special exception, Nokia gives you certain
    24 ** additional rights. These rights are described in the Nokia Qt LGPL
    25 ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
    26 ** package.
     24** In addition, as a special exception, Nokia gives you certain additional
     25** rights.  These rights are described in the Nokia Qt LGPL Exception
     26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
    2727**
    2828** GNU General Public License Usage
     
    3434** met: http://www.gnu.org/copyleft/gpl.html.
    3535**
    36 ** If you are unsure which license is appropriate for your use, please
    37 ** contact the sales department at qt-sales@nokia.com.
     36** If you have questions regarding the use of this file, please contact
     37** Nokia at qt-info@nokia.com.
    3838** $QT_END_LICENSE$
    3939**
     
    5454#include <private/qpdf_p.h>
    5555#include <private/qharfbuzz_p.h>
    56 
    57 #include <private/qpdf_p.h>
    5856
    5957#include "qfontengine_ft_p.h"
     
    194192 * One font file can contain more than one font (bold/italic for example)
    195193 * find the right one and return it.
     194 *
     195 * Returns the freetype face or 0 in case of an empty file or any other problems
     196 * (like not being able to open the file)
    196197 */
    197198QFreetypeFace *QFreetypeFace::getFace(const QFontEngine::FaceId &face_id)
     
    205206
    206207    QFreetypeFace *freetype = freetypeData->faces.value(face_id, 0);
    207     if (!freetype) {
    208         freetype = new QFreetypeFace;
     208    if (freetype) {
     209        freetype->ref.ref();
     210    } else {
     211        QScopedPointer<QFreetypeFace> newFreetype(new QFreetypeFace);
    209212        FT_Face face;
    210213        QFile file(QString::fromUtf8(face_id.filename));
     
    215218            idx.remove(0, 14); // remove ':qmemoryfonts/'
    216219            bool ok = false;
    217             freetype->fontData = qt_fontdata_from_index(idx.toInt(&ok));
     220            newFreetype->fontData = qt_fontdata_from_index(idx.toInt(&ok));
    218221            if (!ok)
    219                 freetype->fontData = QByteArray();
     222                newFreetype->fontData = QByteArray();
    220223        } else if (!(file.fileEngine()->fileFlags(QAbstractFileEngine::FlagsMask) & QAbstractFileEngine::LocalDiskFlag)) {
    221224            if (!file.open(QIODevice::ReadOnly)) {
    222                 delete freetype;
    223225                return 0;
    224226            }
    225             freetype->fontData = file.readAll();
    226         }
    227         if (!freetype->fontData.isEmpty()) {
    228             if (FT_New_Memory_Face(freetypeData->library, (const FT_Byte *)freetype->fontData.constData(), freetype->fontData.size(), face_id.index, &face)) {
    229                 delete freetype;
     227            newFreetype->fontData = file.readAll();
     228        }
     229        if (!newFreetype->fontData.isEmpty()) {
     230            if (FT_New_Memory_Face(freetypeData->library, (const FT_Byte *)newFreetype->fontData.constData(), newFreetype->fontData.size(), face_id.index, &face)) {
    230231                return 0;
    231232            }
    232233        } else if (FT_New_Face(freetypeData->library, face_id.filename, face_id.index, &face)) {
    233             delete freetype;
    234234            return 0;
    235235        }
    236         freetype->face = face;
    237 
    238         freetype->hbFace = qHBNewFace(face, hb_getSFntTable);
    239         freetype->ref = 0;
    240         freetype->xsize = 0;
    241         freetype->ysize = 0;
    242         freetype->matrix.xx = 0x10000;
    243         freetype->matrix.yy = 0x10000;
    244         freetype->matrix.xy = 0;
    245         freetype->matrix.yx = 0;
    246         freetype->unicode_map = 0;
    247         freetype->symbol_map = 0;
     236        newFreetype->face = face;
     237
     238        newFreetype->hbFace = qHBNewFace(face, hb_getSFntTable);
     239        Q_CHECK_PTR(newFreetype->hbFace);
     240        newFreetype->ref = 1;
     241        newFreetype->xsize = 0;
     242        newFreetype->ysize = 0;
     243        newFreetype->matrix.xx = 0x10000;
     244        newFreetype->matrix.yy = 0x10000;
     245        newFreetype->matrix.xy = 0;
     246        newFreetype->matrix.yx = 0;
     247        newFreetype->unicode_map = 0;
     248        newFreetype->symbol_map = 0;
    248249#ifndef QT_NO_FONTCONFIG
    249         freetype->charset = 0;
    250 #endif
    251 
    252         memset(freetype->cmapCache, 0, sizeof(freetype->cmapCache));
    253 
    254         for (int i = 0; i < freetype->face->num_charmaps; ++i) {
    255             FT_CharMap cm = freetype->face->charmaps[i];
     250        newFreetype->charset = 0;
     251#endif
     252
     253        memset(newFreetype->cmapCache, 0, sizeof(newFreetype->cmapCache));
     254
     255        for (int i = 0; i < newFreetype->face->num_charmaps; ++i) {
     256            FT_CharMap cm = newFreetype->face->charmaps[i];
    256257            switch(cm->encoding) {
    257258            case FT_ENCODING_UNICODE:
    258                 freetype->unicode_map = cm;
     259                newFreetype->unicode_map = cm;
    259260                break;
    260261            case FT_ENCODING_APPLE_ROMAN:
    261262            case FT_ENCODING_ADOBE_LATIN_1:
    262                 if (!freetype->unicode_map || freetype->unicode_map->encoding != FT_ENCODING_UNICODE)
    263                     freetype->unicode_map = cm;
     263                if (!newFreetype->unicode_map || newFreetype->unicode_map->encoding != FT_ENCODING_UNICODE)
     264                    newFreetype->unicode_map = cm;
    264265                break;
    265266            case FT_ENCODING_ADOBE_CUSTOM:
    266267            case FT_ENCODING_MS_SYMBOL:
    267                 if (!freetype->symbol_map)
    268                     freetype->symbol_map = cm;
     268                if (!newFreetype->symbol_map)
     269                    newFreetype->symbol_map = cm;
    269270                break;
    270271            default:
     
    273274        }
    274275
    275         if (!FT_IS_SCALABLE(freetype->face) && freetype->face->num_fixed_sizes == 1)
    276             FT_Set_Char_Size (face, X_SIZE(freetype->face, 0), Y_SIZE(freetype->face, 0), 0, 0);
     276        if (!FT_IS_SCALABLE(newFreetype->face) && newFreetype->face->num_fixed_sizes == 1)
     277            FT_Set_Char_Size (face, X_SIZE(newFreetype->face, 0), Y_SIZE(newFreetype->face, 0), 0, 0);
    277278# if 0
    278279        FcChar8 *name;
    279280        FcPatternGetString(pattern, FC_FAMILY, 0, &name);
    280281        qDebug("%s: using maps: default: %x unicode: %x, symbol: %x", name,
    281                freetype->face->charmap ? freetype->face->charmap->encoding : 0,
    282                freetype->unicode_map ? freetype->unicode_map->encoding : 0,
    283                freetype->symbol_map ? freetype->symbol_map->encoding : 0);
     282               newFreetype->face->charmap ? newFreetype->face->charmap->encoding : 0,
     283               newFreetype->unicode_map ? newFreetype->unicode_map->encoding : 0,
     284               newFreetype->symbol_map ? newFreetype->symbol_map->encoding : 0);
    284285
    285286        for (int i = 0; i < 256; i += 8)
    286287            qDebug("    %x: %d %d %d %d %d %d %d %d", i,
    287                    FcCharSetHasChar(freetype->charset, i), FcCharSetHasChar(freetype->charset, i),
    288                    FcCharSetHasChar(freetype->charset, i), FcCharSetHasChar(freetype->charset, i),
    289                    FcCharSetHasChar(freetype->charset, i), FcCharSetHasChar(freetype->charset, i),
    290                    FcCharSetHasChar(freetype->charset, i), FcCharSetHasChar(freetype->charset, i));
    291 #endif
    292 
    293         FT_Set_Charmap(freetype->face, freetype->unicode_map);
    294         freetypeData->faces.insert(face_id, freetype);
    295     }
    296     freetype->ref.ref();
     288                   FcCharSetHasChar(newFreetype->charset, i), FcCharSetHasChar(newFreetype->charset, i),
     289                   FcCharSetHasChar(newFreetype->charset, i), FcCharSetHasChar(newFreetype->charset, i),
     290                   FcCharSetHasChar(newFreetype->charset, i), FcCharSetHasChar(newFreetype->charset, i),
     291                   FcCharSetHasChar(newFreetype->charset, i), FcCharSetHasChar(newFreetype->charset, i));
     292#endif
     293
     294        FT_Set_Charmap(newFreetype->face, newFreetype->unicode_map);
     295        QT_TRY {
     296            freetypeData->faces.insert(face_id, newFreetype.data());
     297        } QT_CATCH(...) {
     298            newFreetype.take()->release(face_id);
     299            // we could return null in principle instead of throwing
     300            QT_RETHROW;
     301        }
     302        freetype = newFreetype.take();
     303    }
    297304    return freetype;
    298305}
     
    308315            FcCharSetDestroy(charset);
    309316#endif
    310         freetypeData->faces.take(face_id);
     317        if(freetypeData->faces.contains(face_id))
     318            freetypeData->faces.take(face_id);
    311319        delete this;
    312320    }
     
    320328void QFreetypeFace::computeSize(const QFontDef &fontDef, int *xsize, int *ysize, bool *outline_drawing)
    321329{
    322     *ysize = fontDef.pixelSize << 6;
     330    *ysize = qRound(fontDef.pixelSize * 64);
    323331    *xsize = *ysize * fontDef.stretch / 100;
    324332    *outline_drawing = false;
     
    380388        p.leading = QFixed::fromFixed(face->size->metrics.height - face->size->metrics.ascender + face->size->metrics.descender);
    381389        p.emSquare = face->size->metrics.y_ppem;
    382         p.boundingBox = QRectF(-p.ascent.toReal(), 0, (p.ascent + p.descent).toReal(), face->size->metrics.max_advance/64.);
     390//        p.boundingBox = QRectF(-p.ascent.toReal(), 0, (p.ascent + p.descent).toReal(), face->size->metrics.max_advance/64.);
     391        p.boundingBox = QRectF(0, -p.ascent.toReal(),
     392                               face->size->metrics.max_advance/64, (p.ascent + p.descent).toReal() );
    383393    }
    384394    p.italicAngle = 0;
     
    609619    transform = false;
    610620    antialias = true;
     621    freetype = 0;
    611622    default_load_flags = 0;
    612623    default_hint_style = HintNone;
     
    614625    lcdFilterType = 0;
    615626#if defined(FT_LCD_FILTER_H)
    616     lcdFilterType = (int) FT_LCD_FILTER_DEFAULT;
     627    lcdFilterType = (int)((quintptr) FT_LCD_FILTER_DEFAULT);
    617628#endif
    618629    defaultFormat = Format_None;
     
    639650    defaultFormat = format;
    640651    this->antialias = antialias;
     652
    641653    if (!antialias)
    642654        glyphFormat = QFontEngineGlyphCache::Raster_Mono;
     655    else if (format == Format_A8)
     656        glyphFormat = QFontEngineGlyphCache::Raster_A8;
     657    else if (format == Format_A32)
     658        glyphFormat = QFontEngineGlyphCache::Raster_RGBMask;
     659
    643660    face_id = faceId;
    644661    freetype = QFreetypeFace::getFace(face_id);
     
    695712
    696713    metrics = face->size->metrics;
     714
    697715#if defined(Q_WS_QWS)
    698716    /*
     
    738756
    739757    // apply our matrix to this, but note that the metrics will not be affected by this.
    740     FT_Matrix matrix = freetype->matrix;
    741758    FT_Face face = lockFace();
    742     matrix = this->matrix;
     759    FT_Matrix matrix = this->matrix;
    743760    FT_Matrix_Multiply(&set->transformationMatrix, &matrix);
    744761    FT_Set_Transform(face, &matrix, 0);
     
    12051222QFixed QFontEngineFT::descent() const
    12061223{
    1207     return QFixed::fromFixed(-metrics.descender);
     1224    // subtract a pixel to work around QFontMetrics's built-in + 1
     1225    return QFixed::fromFixed(-metrics.descender - 64);
    12081226}
    12091227
     
    13811399
    13821400    for (int i = 0; i < num_glyphs; ++i) {
    1383         if (!gs->glyph_data.contains(glyphs[i])
    1384             || gs->glyph_data.value(glyphs[i])->format != format) {
     1401        Glyph *glyph = gs->glyph_data.value(glyphs[i]);
     1402        if (glyph == 0 || glyph->format != format) {
    13851403            if (!face) {
    13861404                face = lockFace();
     
    15211539        return false;
    15221540    }
     1541
     1542#if !defined(QT_NO_FONTCONFIG)
     1543    extern QMutex *qt_fontdatabase_mutex();
     1544    QMutex *mtx = 0;
     1545#endif
    15231546
    15241547    bool mirrored = flags & QTextEngine::RightToLeft;
     
    15341557                glyph_t glyph;
    15351558#if !defined(QT_NO_FONTCONFIG)
     1559                if (!mtx) {
     1560                    mtx = qt_fontdatabase_mutex();
     1561                    mtx->lock();
     1562                }
     1563
    15361564                if (FcCharSetHasChar(freetype->charset, uc)) {
    15371565#else
     
    15621590                uc = QChar::mirroredChar(uc);
    15631591            glyphs->glyphs[glyph_pos] = uc < QFreetypeFace::cmapCacheSize ? freetype->cmapCache[uc] : 0;
    1564             if (!glyphs->glyphs[glyph_pos]
     1592            if (!glyphs->glyphs[glyph_pos]) {
    15651593#if !defined(QT_NO_FONTCONFIG)
    1566                 && FcCharSetHasChar(freetype->charset, uc)
    1567 #endif
    1568                 ) {
    1569             redo:
    1570                 glyph_t glyph = FT_Get_Char_Index(face, uc);
    1571                 if (!glyph && (uc == 0xa0 || uc == 0x9)) {
    1572                     uc = 0x20;
    1573                     goto redo;
     1594                if (!mtx) {
     1595                    mtx = qt_fontdatabase_mutex();
     1596                    mtx->lock();
    15741597                }
    1575                 glyphs->glyphs[glyph_pos] = glyph;
    1576                 if (uc < QFreetypeFace::cmapCacheSize)
    1577                     freetype->cmapCache[uc] = glyph;
     1598
     1599                if (FcCharSetHasChar(freetype->charset, uc))
     1600#endif
     1601                {
     1602                redo:
     1603                    glyph_t glyph = FT_Get_Char_Index(face, uc);
     1604                    if (!glyph && (uc == 0xa0 || uc == 0x9)) {
     1605                        uc = 0x20;
     1606                        goto redo;
     1607                    }
     1608                    glyphs->glyphs[glyph_pos] = glyph;
     1609                    if (uc < QFreetypeFace::cmapCacheSize)
     1610                        freetype->cmapCache[uc] = glyph;
     1611                }
    15781612            }
    15791613            ++glyph_pos;
     
    15831617    *nglyphs = glyph_pos;
    15841618    glyphs->numGlyphs = glyph_pos;
     1619
     1620#if !defined(QT_NO_FONTCONFIG)
     1621    if (mtx)
     1622        mtx->unlock();
     1623#endif
    15851624
    15861625    if (flags & QTextEngine::GlyphIndicesOnly)
     
    17891828    GlyphFormat glyph_format = antialias ? Format_A8 : Format_Mono;
    17901829
    1791     Glyph *glyph = loadGlyph(g, glyph_format);
    1792     if (!glyph)
    1793         return QImage();
     1830    Glyph *glyph = defaultGlyphSet.outline_drawing ? 0 : loadGlyph(g, glyph_format);
     1831    if (!glyph) {
     1832        unlockFace();
     1833        return QFontEngine::alphaMapForGlyph(g);
     1834    }
    17941835
    17951836    const int pitch = antialias ? (glyph->width + 3) & ~3 : ((glyph->width + 31)/32) * 4;
     
    18171858}
    18181859
     1860QImage QFontEngineFT::alphaRGBMapForGlyph(glyph_t g, int margin, const QTransform &t)
     1861{
     1862    if (t.type() > QTransform::TxTranslate)
     1863        return QFontEngine::alphaRGBMapForGlyph(g, margin, t);
     1864
     1865    lockFace();
     1866
     1867    GlyphFormat glyph_format = Format_A32;
     1868
     1869    Glyph *glyph = defaultGlyphSet.outline_drawing ? 0 : loadGlyph(g, glyph_format);
     1870    if (!glyph) {
     1871        unlockFace();
     1872        return QFontEngine::alphaRGBMapForGlyph(g, margin, t);
     1873    }
     1874
     1875    QImage img(glyph->width, glyph->height, QImage::Format_RGB32);
     1876    memcpy(img.bits(), glyph->data, 4 * glyph->width * glyph->height);
     1877    unlockFace();
     1878
     1879    return img;
     1880}
     1881
    18191882void QFontEngineFT::removeGlyphFromCache(glyph_t glyph)
    18201883{
  • trunk/src/gui/text/qfontengine_ft_p.h

    r2 r561  
    22**
    33** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
    4 ** Contact: Qt Software Information (qt-info@nokia.com)
     4** All rights reserved.
     5** Contact: Nokia Corporation (qt-info@nokia.com)
    56**
    67** This file is part of the QtGui module of the Qt Toolkit.
     
    2122** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    2223**
    23 ** In addition, as a special exception, Nokia gives you certain
    24 ** additional rights. These rights are described in the Nokia Qt LGPL
    25 ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
    26 ** package.
     24** In addition, as a special exception, Nokia gives you certain additional
     25** rights.  These rights are described in the Nokia Qt LGPL Exception
     26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
    2727**
    2828** GNU General Public License Usage
     
    3434** met: http://www.gnu.org/copyleft/gpl.html.
    3535**
    36 ** If you are unsure which license is appropriate for your use, please
    37 ** contact the sales department at qt-sales@nokia.com.
     36** If you have questions regarding the use of this file, please contact
     37** Nokia at qt-info@nokia.com.
    3838** $QT_END_LICENSE$
    3939**
     
    120120
    121121private:
     122    friend class QScopedPointerDeleter<QFreetypeFace>;
    122123    QFreetypeFace() : _lock(QMutex::Recursive) {}
    123124    ~QFreetypeFace() {}
     
    227228    virtual void recalcAdvances(QGlyphLayout *glyphs, QTextEngine::ShaperFlags flags) const;
    228229    virtual QImage alphaMapForGlyph(glyph_t);
     230    virtual QImage alphaRGBMapForGlyph(glyph_t, int margin, const QTransform &t);
    229231    virtual void removeGlyphFromCache(glyph_t glyph);
    230232
     
    256258    bool loadGlyphs(QGlyphSet *gs, glyph_t *glyphs, int num_glyphs, GlyphFormat format = Format_Render);
    257259
    258 #if defined(Q_WS_QWS)
     260#if defined(Q_WS_QWS) || defined(Q_OS_SYMBIAN)
    259261    virtual void draw(QPaintEngine * /*p*/, qreal /*x*/, qreal /*y*/, const QTextItemInt & /*si*/) {}
    260262#endif
  • trunk/src/gui/text/qfontengine_mac.mm

    r2 r561  
    22**
    33** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
    4 ** Contact: Qt Software Information (qt-info@nokia.com)
     4** All rights reserved.
     5** Contact: Nokia Corporation (qt-info@nokia.com)
    56**
    67** This file is part of the QtGui module of the Qt Toolkit.
     
    2122** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    2223**
    23 ** In addition, as a special exception, Nokia gives you certain
    24 ** additional rights. These rights are described in the Nokia Qt LGPL
    25 ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
    26 ** package.
     24** In addition, as a special exception, Nokia gives you certain additional
     25** rights.  These rights are described in the Nokia Qt LGPL Exception
     26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
    2727**
    2828** GNU General Public License Usage
     
    3434** met: http://www.gnu.org/copyleft/gpl.html.
    3535**
    36 ** If you are unsure which license is appropriate for your use, please
    37 ** contact the sales department at qt-sales@nokia.com.
     36** If you have questions regarding the use of this file, please contact
     37** Nokia at qt-info@nokia.com.
    3838** $QT_END_LICENSE$
    3939**
     
    120120
    121121
     122
     123void qmacfontengine_gamma_correct(QImage *image)
     124{
     125    extern uchar qt_pow_rgb_gamma[256];
     126
     127    // gamma correct the pixels back to linear color space...
     128    int h = image->height();
     129    int w = image->width();
     130
     131    for (int y=0; y<h; ++y) {
     132        uint *pixels = (uint *) image->scanLine(y);
     133        for (int x=0; x<w; ++x) {
     134            uint p = pixels[x];
     135            uint r = qt_pow_rgb_gamma[qRed(p)];
     136            uint g = qt_pow_rgb_gamma[qGreen(p)];
     137            uint b = qt_pow_rgb_gamma[qBlue(p)];
     138            pixels[x] = (r << 16) | (g << 8) | b | 0xff000000;
     139        }
     140    }
     141}
     142
     143
    122144#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5
    123145QCoreTextFontEngineMulti::QCoreTextFontEngineMulti(const ATSFontFamilyRef &, const ATSFontRef &atsFontRef, const QFontDef &fontDef, bool kerning)
     
    136158        break;
    137159    }
    138    
     160
    139161    QCFString name;
    140162    ATSFontGetName(atsFontRef, kATSOptionFlagsDefault, &name);
     163
    141164    QCFType<CTFontDescriptorRef> descriptor = CTFontDescriptorCreateWithNameAndSize(name, fontDef.pixelSize);
    142     QCFType<CTFontRef> baseFont = CTFontCreateWithFontDescriptor(descriptor, fontDef.pixelSize, 0); 
     165    QCFType<CTFontRef> baseFont = CTFontCreateWithFontDescriptor(descriptor, fontDef.pixelSize, 0);
    143166    ctfont = CTFontCreateCopyWithSymbolicTraits(baseFont, fontDef.pixelSize, 0, symbolicTraits, symbolicTraits);
    144167
     
    157180        float zero = 0.0;
    158181        QCFType<CFNumberRef> noKern = CFNumberCreate(kCFAllocatorDefault, kCFNumberFloatType, &zero);
    159         CFDictionaryAddValue(attributeDict, kCTKernAttributeName, &noKern);
     182        CFDictionaryAddValue(attributeDict, kCTKernAttributeName, noKern);
    160183    }
    161184
     
    163186    fe->ref.ref();
    164187    engines.append(fe);
    165    
     188
    166189}
    167190
     
    177200            return i;
    178201    }
    179    
     202
    180203    QCoreTextFontEngineMulti *that = const_cast<QCoreTextFontEngineMulti *>(this);
    181204    QCoreTextFontEngine *fe = new QCoreTextFontEngine(id, fontDef, that);
     
    228251            const uint fontIndex = (fontIndexForFont(runFont) << 24);
    229252            //NSLog(@"Run Font Name = %@", CTFontCopyFamilyName(runFont));
    230             QVarLengthArray<CGGlyph, 512> cgglyphs(0);           
     253            QVarLengthArray<CGGlyph, 512> cgglyphs(0);
    231254            const CGGlyph *tmpGlyphs = CTRunGetGlyphsPtr(run);
    232255            if (!tmpGlyphs) {
     
    261284                CFIndex k = 0;
    262285                CFIndex i = 0;
    263                 for (i = stringRange.location; 
     286                for (i = stringRange.location;
    264287                     (i < stringRange.location + stringRange.length) && (k < glyphCount); ++i) {
    265288                    if (tmpIndices[k * rtlSign + rtlOffset] == i || i == stringRange.location) {
     
    382405QFixed QCoreTextFontEngine::descent() const
    383406{
    384     return QFixed::fromReal(CTFontGetDescent(ctfont)).ceil();
     407    // subtract a pixel to even out the historical +1 in QFontMetrics::height().
     408    // Fix in Qt 5.
     409    return QFixed::fromReal(CTFontGetDescent(ctfont)).ceil() - 1;
    385410}
    386411QFixed QCoreTextFontEngine::leading() const
     
    426451    if (glyphs.size() == 0)
    427452        return;
    428    
     453
    429454    CGContextSetFontSize(ctx, fontDef.pixelSize);
    430    
     455
    431456    CGAffineTransform oldTextMatrix = CGContextGetTextMatrix(ctx);
    432    
     457
    433458    CGAffineTransform cgMatrix = CGAffineTransformMake(1, 0, 0, -1, 0, -paintDeviceHeight);
    434    
     459
    435460    CGAffineTransformConcat(cgMatrix, oldTextMatrix);
    436    
     461
    437462    if (synthesisFlags & QFontEngine::SynthesizedItalic)
    438463        cgMatrix = CGAffineTransformConcat(cgMatrix, CGAffineTransformMake(1, 0, -tanf(14 * acosf(0) / 90), 1, 0, 0));
    439    
     464
    440465// ###    cgMatrix = CGAffineTransformConcat(cgMatrix, transform);
    441    
     466
    442467    CGContextSetTextMatrix(ctx, cgMatrix);
    443    
     468
    444469    CGContextSetTextDrawingMode(ctx, kCGTextFill);
    445    
    446    
     470
     471
    447472    QVarLengthArray<CGSize> advances(glyphs.size());
    448473    QVarLengthArray<CGGlyph> cgGlyphs(glyphs.size());
    449    
     474
    450475    for (int i = 0; i < glyphs.size() - 1; ++i) {
    451476        advances[i].width = (positions[i + 1].x - positions[i].x).toReal();
     
    456481    advances[glyphs.size() - 1].height = 0;
    457482    cgGlyphs[glyphs.size() - 1] = glyphs[glyphs.size() - 1];
    458    
     483
    459484    CGContextSetFont(ctx, cgFont);
    460485    //NSLog(@"Font inDraw %@  ctfont %@", CGFontCopyFullName(cgFont), CTFontCopyFamilyName(ctfont));
    461    
     486
    462487    CGContextSetTextPosition(ctx, positions[0].x.toReal(), positions[0].y.toReal());
    463    
     488
    464489    CGContextShowGlyphsWithAdvances(ctx, cgGlyphs.data(), advances.data(), glyphs.size());
    465    
     490
    466491    if (synthesisFlags & QFontEngine::SynthesizedBold) {
    467492        CGContextSetTextPosition(ctx, positions[0].x.toReal() + 0.5 * lineThickness().toReal(),
    468493                                 positions[0].y.toReal());
    469        
     494
    470495        CGContextShowGlyphsWithAdvances(ctx, cgGlyphs.data(), advances.data(), glyphs.size());
    471496    }
    472    
     497
    473498    CGContextSetTextMatrix(ctx, oldTextMatrix);
    474499}
     
    524549
    525550    if (synthesisFlags & QFontEngine::SynthesizedItalic)
    526         cgMatrix = CGAffineTransformConcat(cgMatrix, CGAffineTransformMake(1, 0, tanf(14 * acosf(0) / 90), 1, 0, 0));
     551        cgMatrix = CGAffineTransformConcat(cgMatrix, CGAffineTransformMake(1, 0, -tanf(14 * acosf(0) / 90), 1, 0, 0));
    527552
    528553
     
    534559}
    535560
    536 QImage QCoreTextFontEngine::alphaMapForGlyph(glyph_t glyph)
     561QImage QCoreTextFontEngine::imageForGlyph(glyph_t glyph, int margin, bool aa)
    537562{
    538563    const glyph_metrics_t br = boundingBox(glyph);
     
    541566
    542567    CGColorSpaceRef colorspace = QCoreGraphicsPaintEngine::macGenericColorSpace();
    543 #if (MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_4)
    544568    uint cgflags = kCGImageAlphaNoneSkipFirst;
    545569#ifdef kCGBitmapByteOrder32Host //only needed because CGImage.h added symbols in the minor version
    546     if(QSysInfo::MacintoshVersion >= QSysInfo::MV_10_4)
    547         cgflags |= kCGBitmapByteOrder32Host;
    548 #endif
    549 #else
    550     CGImageAlphaInfo cgflags = kCGImageAlphaNoneSkipFirst;
     570    cgflags |= kCGBitmapByteOrder32Host;
    551571#endif
    552572    CGContextRef ctx = CGBitmapContextCreate(im.bits(), im.width(), im.height(),
     
    554574                                             cgflags);
    555575    CGContextSetFontSize(ctx, fontDef.pixelSize);
    556     CGContextSetShouldAntialias(ctx, fontDef.pointSize > qt_antialiasing_threshold && !(fontDef.styleStrategy & QFont::NoAntialias));
     576    CGContextSetShouldAntialias(ctx, aa ||
     577                                (fontDef.pointSize > qt_antialiasing_threshold
     578                                 && !(fontDef.styleStrategy & QFont::NoAntialias)));
     579    CGContextSetShouldSmoothFonts(ctx, aa);
    557580    CGAffineTransform oldTextMatrix = CGContextGetTextMatrix(ctx);
    558581    CGAffineTransform cgMatrix = CGAffineTransformMake(1, 0, 0, 1, 0, 0);
     
    588611
    589612    CGContextRelease(ctx);
     613
     614    return im;
     615}
     616
     617QImage QCoreTextFontEngine::alphaMapForGlyph(glyph_t glyph)
     618{
     619    QImage im = imageForGlyph(glyph, 0, false);
    590620
    591621    QImage indexed(im.width(), im.height(), QImage::Format_Indexed8);
     
    608638}
    609639
     640QImage QCoreTextFontEngine::alphaRGBMapForGlyph(glyph_t glyph, int margin, const QTransform &x)
     641{
     642    if (x.type() >= QTransform::TxScale)
     643        return QFontEngine::alphaRGBMapForGlyph(glyph, margin, x);
     644
     645    QImage im = imageForGlyph(glyph, margin, true);
     646    qmacfontengine_gamma_correct(&im);
     647    return im;
     648}
     649
    610650void QCoreTextFontEngine::recalcAdvances(int numGlyphs, QGlyphLayout *glyphs, QTextEngine::ShaperFlags flags) const
    611651{
     
    623663bool QCoreTextFontEngine::canRender(const QChar *string, int len)
    624664{
    625     QCFType<CTFontRef> retFont = CTFontCreateForString(ctfont, 
     665    QCFType<CTFontRef> retFont = CTFontCreateForString(ctfont,
    626666                  QCFType<CFStringRef>(CFStringCreateWithCharactersNoCopy(0,
    627667                                                              reinterpret_cast<const UniChar *>(string),
     
    673713        if (fontDef.weight >= QFont::Bold)
    674714            fntStyle |= ::bold;
    675         if (fontDef.style != QFont::StyleNormal) 
     715        if (fontDef.style != QFont::StyleNormal)
    676716            fntStyle |= ::italic;
    677717
     
    793833                           && str[i+1].unicode() >= 0xdc00 && str[i+1].unicode() < 0xe000);
    794834        }
    795         Q_ASSERT(*nfo->numGlyphs == item->length - surrogates);
    796835#endif
    797836        for (nextCharStop = item->from; nextCharStop < item->from + item->length; ++nextCharStop)
     
    819858
    820859        if (glyphId != 0xffff || i == 0) {
    821             nfo->glyphs->glyphs[i] = (glyphId & 0x00ffffff) | (fontIdx << 24);
    822 
    823             nfo->glyphs->advances_y[i] = yAdvance;
    824             nfo->glyphs->advances_x[i] = xAdvance;
     860            if (i < nfo->glyphs->numGlyphs)
     861            {
     862                nfo->glyphs->glyphs[i] = (glyphId & 0x00ffffff) | (fontIdx << 24);
     863
     864                nfo->glyphs->advances_y[i] = yAdvance;
     865                nfo->glyphs->advances_x[i] = xAdvance;
     866            }
    825867        } else {
    826868            // ATSUI gives us 0xffff as glyph id at the index in the glyph array for
     
    956998        tmpItem.glyphs = shaperItem.glyphs.mid(glyphIdx, glyphCount);
    957999        tmpItem.log_clusters = shaperItem.log_clusters + charIdx;
    958         if (!stringToCMapInternal(tmpItem.string + tmpItem.from, tmpItem.length, 
     1000        if (!stringToCMapInternal(tmpItem.string + tmpItem.from, tmpItem.length,
    9591001                                  &tmpItem.glyphs, &glyphCount, flags,
    9601002                                  &tmpItem)) {
     
    9921034    nfo.shaperItem = shaperItem;
    9931035
     1036    int prevNumGlyphs = *nglyphs;
     1037
    9941038    QVarLengthArray<int> mappedFonts(len);
    9951039    for (int i = 0; i < len; ++i)
     
    10181062                                       ;
    10191063
    1020         if (!(flags & QTextEngine::DesignMetrics)) {
    1021             layopts |= kATSLineFractDisable | kATSLineUseDeviceMetrics
    1022                        | kATSLineDisableAutoAdjustDisplayPos;
    1023         }
     1064        layopts |= kATSLineUseDeviceMetrics;
    10241065
    10251066        if (fontDef.styleStrategy & QFont::NoAntialias)
     
    11061147
    11071148    ATSUClearLayoutCache(textLayout, kATSUFromTextBeginning);
     1149    if (prevNumGlyphs < *nfo.numGlyphs)
     1150        return false;
    11081151    return true;
    11091152}
     
    12221265    else
    12231266        transform = CGAffineTransformIdentity;
    1224    
     1267
    12251268    ATSUTextMeasurement metric;
    12261269
    12271270    ATSUGetAttribute(style, kATSUAscentTag, sizeof(metric), &metric, 0);
    12281271    m_ascent = FixRound(metric);
    1229    
     1272
    12301273    ATSUGetAttribute(style, kATSUDescentTag, sizeof(metric), &metric, 0);
    12311274    m_descent = FixRound(metric);
     
    13661409QFixed QFontEngineMac::descent() const
    13671410{
    1368     return m_descent;
     1411    // subtract a pixel to even out the historical +1 in QFontMetrics::height().
     1412    // Fix in Qt 5.
     1413    return m_descent - 1;
    13691414}
    13701415
     
    14231468}
    14241469
    1425 QImage QFontEngineMac::alphaMapForGlyph(glyph_t glyph)
     1470
     1471/*!
     1472  Helper function for alphaMapForGlyph and alphaRGBMapForGlyph. The two are identical, except for
     1473  the subpixel antialiasing...
     1474*/
     1475QImage QFontEngineMac::imageForGlyph(glyph_t glyph, int margin, bool colorful)
    14261476{
    14271477    const glyph_metrics_t br = boundingBox(glyph);
    14281478    QImage im(qRound(br.width)+2, qRound(br.height)+4, QImage::Format_RGB32);
    1429     im.fill(0);
     1479    im.fill(0xff000000);
    14301480
    14311481    CGColorSpaceRef colorspace = QCoreGraphicsPaintEngine::macGenericColorSpace();
    1432 #if (MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_4)
    14331482    uint cgflags = kCGImageAlphaNoneSkipFirst;
    14341483#ifdef kCGBitmapByteOrder32Host //only needed because CGImage.h added symbols in the minor version
    1435     if(QSysInfo::MacintoshVersion >= QSysInfo::MV_10_4)
    1436         cgflags |= kCGBitmapByteOrder32Host;
    1437 #endif
    1438 #else
    1439     CGImageAlphaInfo cgflags = kCGImageAlphaNoneSkipFirst;
     1484    cgflags |= kCGBitmapByteOrder32Host;
    14401485#endif
    14411486    CGContextRef ctx = CGBitmapContextCreate(im.bits(), im.width(), im.height(),
     
    14451490    CGContextSetShouldAntialias(ctx, fontDef.pointSize > qt_antialiasing_threshold && !(fontDef.styleStrategy & QFont::NoAntialias));
    14461491    // turn off sub-pixel hinting - no support for that in OpenGL
    1447     CGContextSetShouldSmoothFonts(ctx, false);
     1492    CGContextSetShouldSmoothFonts(ctx, colorful);
    14481493    CGAffineTransform oldTextMatrix = CGContextGetTextMatrix(ctx);
    14491494    CGAffineTransform cgMatrix = CGAffineTransformMake(1, 0, 0, 1, 0, 0);
     
    14761521
    14771522    CGContextRelease(ctx);
     1523
     1524    return im;
     1525}
     1526
     1527QImage QFontEngineMac::alphaMapForGlyph(glyph_t glyph)
     1528{
     1529    QImage im = imageForGlyph(glyph, 2, false);
    14781530
    14791531    QImage indexed(im.width(), im.height(), QImage::Format_Indexed8);
     
    14961548}
    14971549
     1550QImage QFontEngineMac::alphaRGBMapForGlyph(glyph_t glyph, int margin, const QTransform &t)
     1551{
     1552    QImage im = imageForGlyph(glyph, margin, true);
     1553
     1554    if (t.type() >= QTransform::TxScale) {
     1555        im = im.transformed(t);
     1556    }
     1557
     1558    qmacfontengine_gamma_correct(&im);
     1559
     1560    return im;
     1561}
     1562
     1563
    14981564bool QFontEngineMac::canRender(const QChar *string, int len)
    14991565{
     
    15641630    FaceId ret;
    15651631#if (MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5)
     1632if (QSysInfo::MacintoshVersion >= QSysInfo::MV_10_5) {
    15661633    // CTFontGetPlatformFont
    15671634    FSRef ref;
     
    15711638    ret.index = fontID;
    15721639    FSRefMakePath(&ref, (UInt8 *)ret.filename.data(), ret.filename.size());
    1573 #else
     1640}else
     1641#endif
     1642{
    15741643    FSSpec spec;
    15751644    if (ATSFontGetFileSpecification(FMGetATSFontRefFromFont(fontID), &spec) != noErr)
     
    15811650    ret.index = fontID;
    15821651    FSRefMakePath(&ref, (UInt8 *)ret.filename.data(), ret.filename.size());
    1583 #endif
     1652}
    15841653    return ret;
    15851654}
     
    16491718       lw = qFromBigEndian<quint16>(lw);
    16501719    props.lineWidth = lw;
    1651    
     1720
    16521721    // CTFontCopyPostScriptName
    16531722    QCFString psName;
     
    16641733
    16651734    int emSquare = properties().emSquare.toInt();
    1666    
     1735
    16671736    const int maxAttributeCount = 4;
    16681737    ATSUAttributeTag tags[maxAttributeCount + 1];
     
    16761745    values[attributeCount] = &size;
    16771746    ++attributeCount;
    1678    
     1747
    16791748    Q_ASSERT(attributeCount < maxAttributeCount + 1);
    16801749    OSStatus err = ATSUSetAttributes(unscaledStyle, attributeCount, tags, sizes, values);
  • trunk/src/gui/text/qfontengine_p.h

    r125 r561  
    22**
    33** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
    4 ** Contact: Qt Software Information (qt-info@nokia.com)
     4** All rights reserved.
     5** Contact: Nokia Corporation (qt-info@nokia.com)
    56**
    67** This file is part of the QtGui module of the Qt Toolkit.
     
    2122** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    2223**
    23 ** In addition, as a special exception, Nokia gives you certain
    24 ** additional rights. These rights are described in the Nokia Qt LGPL
    25 ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
    26 ** package.
     24** In addition, as a special exception, Nokia gives you certain additional
     25** rights.  These rights are described in the Nokia Qt LGPL Exception
     26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
    2727**
    2828** GNU General Public License Usage
     
    3434** met: http://www.gnu.org/copyleft/gpl.html.
    3535**
    36 ** If you are unsure which license is appropriate for your use, please
    37 ** contact the sales department at qt-sales@nokia.com.
     36** If you have questions regarding the use of this file, please contact
     37** Nokia at qt-info@nokia.com.
    3838** $QT_END_LICENSE$
    3939**
     
    5757#include "QtCore/qatomic.h"
    5858#include <QtCore/qvarlengtharray.h>
     59#include <QtCore/QLinkedList>
    5960#include "private/qtextengine_p.h"
    6061#include "private/qfont_p.h"
     
    7172#endif
    7273
    73 #include "qfontengineglyphcache_p.h"
     74#include <private/qfontengineglyphcache_p.h>
    7475
    7576struct glyph_metrics_t;
     
    9495class Q_GUI_EXPORT QFontEngine : public QObject
    9596{
    96     Q_OBJECT
    9797public:
    9898    enum Type {
     
    109109        Mac,
    110110
    111         // Trolltech QWS types
     111        // QWS types
    112112        Freetype,
    113113        QPF1,
    114114        QPF2,
    115115        Proxy,
     116
     117        // S60 types
     118        S60FontEngine, // Cannot be simply called "S60". Reason is qt_s60Data.h
     119
    116120        TestFontEngine = 0x1000
    117121    };
     
    165169    virtual void doKerning(QGlyphLayout *, QTextEngine::ShaperFlags) const;
    166170
    167 #if !defined(Q_WS_X11) && !defined(Q_WS_WIN) && !defined(Q_WS_PM) && !defined(Q_WS_MAC)
     171#if !defined(Q_WS_X11) && !defined(Q_WS_WIN) && !defined(Q_WS_MAC) && !defined(Q_OS_SYMBIAN) && !defined(Q_WS_PM)
    168172    virtual void draw(QPaintEngine *p, qreal x, qreal y, const QTextItemInt &si) = 0;
    169173#endif
     
    179183     * Returns an image indexed_8 with index values ranging from 0=fully transparant to 255=opaque
    180184     */
    181     virtual QImage alphaMapForGlyph(glyph_t) = 0;
     185    virtual QImage alphaMapForGlyph(glyph_t);
    182186    virtual QImage alphaMapForGlyph(glyph_t, const QTransform &t);
    183187    virtual QImage alphaRGBMapForGlyph(glyph_t, int margin, const QTransform &t);
     
    217221
    218222    void setGlyphCache(void *key, QFontEngineGlyphCache *data);
    219     void setGlyphCache(QFontEngineGlyphCache::Type key, QFontEngineGlyphCache *data);
    220     QFontEngineGlyphCache *glyphCache(void *key, const QTransform &transform) const;
    221     QFontEngineGlyphCache *glyphCache(QFontEngineGlyphCache::Type key, const QTransform &transform) const;
     223    QFontEngineGlyphCache *glyphCache(void *key, QFontEngineGlyphCache::Type type, const QTransform &transform) const;
    222224
    223225    static const uchar *getCMap(const uchar *table, uint tableSize, bool *isSymbolFont, int *cmapSize);
     
    232234    mutable HB_FontRec hbFont;
    233235    mutable HB_Face hbFace;
    234 #if defined(Q_WS_WIN) || defined(Q_WS_PM) || defined(Q_WS_X11) || defined(Q_WS_QWS)
     236#if defined(Q_WS_WIN) || defined(Q_WS_X11) || defined(Q_WS_QWS) || defined(Q_OS_SYMBIAN) || defined(Q_WS_PM)
    235237    struct KernPair {
    236238        uint left_right;
     
    248250    int glyphFormat;
    249251
     252protected:
     253    static const QVector<QRgb> &grayPalette();
     254
    250255private:
    251     /// remove old entries from the glyph cache. Helper method for the setGlyphCache ones.
    252     void expireGlyphCache();
    253 
    254     GlyphPointerHash m_glyphPointerHash;
    255     GlyphIntHash m_glyphIntHash;
    256     mutable QList<QFontEngineGlyphCache*> m_glyphCacheQueue;
     256    struct GlyphCacheEntry {
     257        void *context;
     258        QFontEngineGlyphCache *cache;
     259        bool operator==(const GlyphCacheEntry &other) { return context == other.context && cache == other.cache; }
     260    };
     261
     262    mutable QLinkedList<GlyphCacheEntry> m_glyphCaches;
    257263};
    258264
     
    323329    virtual void recalcAdvances(QGlyphLayout *, QTextEngine::ShaperFlags) const;
    324330
    325 #if !defined(Q_WS_X11) && !defined(Q_WS_WIN) && !defined(Q_WS_PM) && !defined(Q_WS_MAC)
     331#if !defined(Q_WS_X11) && !defined(Q_WS_WIN) && !defined(Q_WS_MAC) && !defined(Q_OS_SYMBIAN) && !defined(Q_WS_PM)
    326332    void draw(QPaintEngine *p, qreal x, qreal y, const QTextItemInt &si);
    327333#endif
     
    354360};
    355361
    356 class Q_GUI_EXPORT QFontEngineMulti : public QFontEngine
     362class QFontEngineMulti : public QFontEngine
    357363{
    358364public:
     
    390396    { return "Multi"; }
    391397
    392     QFontEngine *engine(int at) const;
     398    QFontEngine *engine(int at) const
     399    {Q_ASSERT(at < engines.size()); return engines.at(at); }
     400
    393401
    394402protected:
     
    441449    virtual void getUnscaledGlyph(glyph_t glyph, QPainterPath *path, glyph_metrics_t *metrics);
    442450    virtual QImage alphaMapForGlyph(glyph_t);
     451    virtual QImage alphaRGBMapForGlyph(glyph_t, int margin, const QTransform &t);
    443452    virtual qreal minRightBearing() const;
    444453    virtual qreal minLeftBearing() const;
    445454
    446455
    447 
    448456private:
     457    QImage imageForGlyph(glyph_t glyph, int margin, bool colorful);
    449458    CTFontRef ctfont;
    450459    CGFontRef cgFont;
     
    526535    virtual void getUnscaledGlyph(glyph_t glyph, QPainterPath *path, glyph_metrics_t *metrics);
    527536    virtual QImage alphaMapForGlyph(glyph_t);
     537    virtual QImage alphaRGBMapForGlyph(glyph_t, int margin, const QTransform &t);
    528538
    529539private:
     540    QImage imageForGlyph(glyph_t glyph, int margin, bool colorful);
     541
    530542    ATSUFontID fontID;
    531543    QCFType<CGFontRef> cgFont;
     
    615627#endif
    616628
     629#if defined(Q_OS_SYMBIAN) && !defined(QT_NO_FREETYPE)
     630#   include "private/qfontengine_ft_p.h"
     631#endif
     632
    617633#endif // QFONTENGINE_P_H
  • trunk/src/gui/text/qfontengine_qpf.cpp

    r2 r561  
    22**
    33** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
    4 ** Contact: Qt Software Information (qt-info@nokia.com)
     4** All rights reserved.
     5** Contact: Nokia Corporation (qt-info@nokia.com)
    56**
    67** This file is part of the QtGui module of the Qt Toolkit.
     
    2122** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    2223**
    23 ** In addition, as a special exception, Nokia gives you certain
    24 ** additional rights. These rights are described in the Nokia Qt LGPL
    25 ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
    26 ** package.
     24** In addition, as a special exception, Nokia gives you certain additional
     25** rights.  These rights are described in the Nokia Qt LGPL Exception
     26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
    2727**
    2828** GNU General Public License Usage
     
    3434** met: http://www.gnu.org/copyleft/gpl.html.
    3535**
    36 ** If you are unsure which license is appropriate for your use, please
    37 ** contact the sales department at qt-sales@nokia.com.
     36** If you have questions regarding the use of this file, please contact
     37** Nokia at qt-info@nokia.com.
    3838** $QT_END_LICENSE$
    3939**
     
    5252#include "private/qfontengine_ft_p.h"
    5353#endif
     54#include "private/qcore_unix_p.h" // overrides QT_OPEN
    5455
    5556// for mmap
     
    6667#ifndef QT_NO_QWS_QPF2
    6768
     69#include "qpfutil.cpp"
     70
    6871QT_BEGIN_INCLUDE_NAMESPACE
    69 #include "qpfutil.cpp"
    7072
    7173#if defined(Q_WS_QWS)
     
    253255        const QByteArray fileName = QFile::encodeName(dir.absoluteFilePath(dir[i]));
    254256
    255         int fd = ::open(fileName.constData(), O_RDONLY);
     257        int fd = QT_OPEN(fileName.constData(), O_RDONLY, 0);
    256258        if (fd >= 0) {
    257259            void *header = ::mmap(0, sizeof(QFontEngineQPF::Header), PROT_READ, MAP_SHARED, fd, 0);
     
    266268                ::munmap(header, sizeof(QFontEngineQPF::Header));
    267269            }
    268             ::close(fd);
     270            QT_CLOSE(fd);
    269271        }
    270272    }
     
    309311
    310312#if defined(DEBUG_FONTENGINE)
    311     qDebug() << "QFontEngineQPF::QFontEngineQPF( fd =" << fd << ", renderingFontEngine =" << renderingFontEngine << ")";
     313    qDebug() << "QFontEngineQPF::QFontEngineQPF( fd =" << fd << ", renderingFontEngine =" << renderingFontEngine << ')';
    312314#endif
    313315
     
    317319            return;
    318320
    319         fileName = fontDef.family.toLower() + QLatin1String("_")
     321        fileName = fontDef.family.toLower() + QLatin1Char('_')
    320322                   + QString::number(fontDef.pixelSize)
    321                    + QLatin1String("_") + QString::number(fontDef.weight)
     323                   + QLatin1Char('_') + QString::number(fontDef.weight)
    322324                   + (fontDef.style != QFont::StyleNormal ?
    323325                      QLatin1String("_italic") : QLatin1String(""))
     
    326328        fileName.prepend(qws_fontCacheDir());
    327329
    328         const QByteArray encodedName = QFile::encodeName(fileName);
    329         if (::access(encodedName, F_OK) == 0) {
     330        encodedFileName = QFile::encodeName(fileName);
     331        if (::access(encodedFileName, F_OK) == 0) {
    330332#if defined(DEBUG_FONTENGINE)
    331333            qDebug() << "found existing qpf:" << fileName;
    332334#endif
    333             if (::access(encodedName, W_OK | R_OK) == 0)
    334                 fd = ::open(encodedName, O_RDWR);
    335             else if (::access(encodedName, R_OK) == 0)
    336                 fd = ::open(encodedName, O_RDONLY);
     335            if (::access(encodedFileName, W_OK | R_OK) == 0) {
     336                fd = QT_OPEN(encodedFileName, O_RDWR);
     337            }
     338            // read-write access failed - try read-only access
     339            if (fd == -1 && ::access(encodedFileName, R_OK) == 0) {
     340                fd = QT_OPEN(encodedFileName, O_RDONLY);
     341                if (fd == -1) {
     342#if defined(DEBUG_FONTENGINE)
     343                    qErrnoWarning("QFontEngineQPF: unable to open %s", encodedName.constData());
     344#endif
     345                    return;
     346                }
     347            }
     348            if (fd == -1) {
     349#if defined(DEBUG_FONTENGINE)
     350                qWarning("QFontEngineQPF: insufficient access rights to %s", encodedName.constData());
     351#endif
     352                return;
     353            }
    337354        } else {
    338355#if defined(DEBUG_FONTENGINE)
     
    340357#endif
    341358            if (::access(QFile::encodeName(qws_fontCacheDir()), W_OK) == 0) {
    342                 fd = ::open(encodedName, O_RDWR | O_EXCL | O_CREAT, 0644);
     359                fd = QT_OPEN(encodedFileName, O_RDWR | O_EXCL | O_CREAT, 0644);
     360                if (fd == -1) {
     361#if defined(DEBUG_FONTENGINE)
     362                    qErrnoWarning(errno, "QFontEngineQPF: open() failed for %s", encodedName.constData());
     363#endif
     364                    return;
     365                }
    343366
    344367                QBuffer buffer;
     
    348371                buffer.close();
    349372                const QByteArray &data = buffer.data();
    350                 ::write(fd, data.constData(), data.size());
     373                if (QT_WRITE(fd, data.constData(), data.size()) == -1) {
     374#if defined(DEBUG_FONTENGINE)
     375                    qErrnoWarning(errno, "QFontEngineQPF: write() failed for %s", encodedName.constData());
     376#endif
     377                    return;
     378                }
     379            } else {
     380#if defined(DEBUG_FONTENGINE)
     381                qErrnoWarning(errno, "QFontEngineQPF: access() failed for %s", qPrintable(qws_fontCacheDir()));
     382#endif
     383                return;
    351384            }
    352385        }
     
    356389    if (QT_FSTAT(fd, &st)) {
    357390#if defined(DEBUG_FONTENGINE)
    358         qDebug() << "stat failed!";
     391        qErrnoWarning(errno, "QFontEngineQPF: fstat failed!");
    359392#endif
    360393        return;
     
    475508#if defined(Q_WS_QWS)
    476509    if (isValid() && renderingFontEngine)
    477         qt_fbdpy->sendFontCommand(QWSFontCommand::StartedUsingFont, QFile::encodeName(fileName));
     510        qt_fbdpy->sendFontCommand(QWSFontCommand::StartedUsingFont, encodedFileName);
    478511#endif
    479512}
     
    482515{
    483516#if defined(Q_WS_QWS)
    484     if (isValid() && renderingFontEngine)
    485         qt_fbdpy->sendFontCommand(QWSFontCommand::StoppedUsingFont, QFile::encodeName(fileName));
     517    if (isValid() && renderingFontEngine) {
     518        QT_TRY {
     519            qt_fbdpy->sendFontCommand(QWSFontCommand::StoppedUsingFont, encodedFileName);
     520        } QT_CATCH(...) {
     521            qDebug("QFontEngineQPF::~QFontEngineQPF: Out of memory");
     522            // ignore.
     523        }
     524    }
    486525#endif
    487526    delete renderingFontEngine;
    488     if (fontData)
    489         munmap((void *)fontData, dataSize);
     527    if (fontData) {
     528        if (munmap((void *)fontData, dataSize) == -1) {
     529#if defined(DEBUG_FONTENGINE)
     530            qErrnoWarning(errno, "~QFontEngineQPF: Unable to munmap");
     531#endif
     532        }
     533    }
    490534    if (fd != -1)
    491535        ::close(fd);
     
    551595            QChar c(uc);
    552596            if (!findGlyph(glyphs[glyph_pos].glyph) && !seenGlyphs.contains(c))
    553                 qDebug() << "glyph for character" << c << "/" << hex << uc << "is" << dec << glyphs[glyph_pos].glyph;
     597                qDebug() << "glyph for character" << c << '/' << hex << uc << "is" << dec << glyphs[glyph_pos].glyph;
    554598
    555599            seenGlyphs.insert(c);
     
    585629    const Glyph *glyph = findGlyph(g);
    586630    if (!glyph)
    587         QImage();
     631        return QImage();
    588632
    589633    const uchar *bits = ((const uchar *) glyph) + sizeof(Glyph);
     
    591635    QImage image(glyph->width, glyph->height, QImage::Format_Indexed8);
    592636    for (int j=0; j<256; ++j)
    593         image.setColor(j, 0xff000000 | j | (j<<8) | (j<<16));
     637        image.setColor(j, qRgba(0, 0, 0, j));
    594638
    595639    for (int i=0; i<glyph->height; ++i) {
     
    776820
    777821    // ### not perfect
    778     const int ysize = fontDef.pixelSize << 6;
     822    const int ysize = qRound(fontDef.pixelSize * qreal(64));
    779823    const int xsize = ysize;
    780824
     
    894938    g.advance = qRound(metrics.xoff);
    895939
    896     ::write(fd, &g, sizeof(g));
    897     ::write(fd, img.bits(), img.numBytes());
     940    QT_WRITE(fd, &g, sizeof(g));
     941    QT_WRITE(fd, img.bits(), img.byteCount());
    898942
    899943    glyphPos = oldSize - glyphDataOffset;
     
    905949    gmap[glyph] = qToBigEndian(glyphPos);
    906950
    907     glyphDataSize = glyphPos + sizeof(g) + img.numBytes();
     951    glyphDataSize = glyphPos + sizeof(g) + img.byteCount();
    908952    quint32 *blockSizePtr = (quint32 *)(fontData + glyphDataOffset - 4);
    909953    *blockSizePtr = qToBigEndian(glyphDataSize);
     
    11291173#endif // QT_NO_QWS_QPF2
    11301174
     1175/*
     1176    Creates a new multi qws engine.
     1177
     1178    This function takes ownership of the QFontEngine, increasing it's refcount.
     1179*/
    11311180QFontEngineMultiQWS::QFontEngineMultiQWS(QFontEngine *fe, int _script, const QStringList &fallbacks)
    11321181    : QFontEngineMulti(fallbacks.size() + 1),
  • trunk/src/gui/text/qfontengine_qpf_p.h

    r2 r561  
    22**
    33** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
    4 ** Contact: Qt Software Information (qt-info@nokia.com)
     4** All rights reserved.
     5** Contact: Nokia Corporation (qt-info@nokia.com)
    56**
    67** This file is part of the QtGui module of the Qt Toolkit.
     
    2122** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    2223**
    23 ** In addition, as a special exception, Nokia gives you certain
    24 ** additional rights. These rights are described in the Nokia Qt LGPL
    25 ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
    26 ** package.
     24** In addition, as a special exception, Nokia gives you certain additional
     25** rights.  These rights are described in the Nokia Qt LGPL Exception
     26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
    2727**
    2828** GNU General Public License Usage
     
    3434** met: http://www.gnu.org/copyleft/gpl.html.
    3535**
    36 ** If you are unsure which license is appropriate for your use, please
    37 ** contact the sales department at qt-sales@nokia.com.
     36** If you have questions regarding the use of this file, please contact
     37** Nokia at qt-info@nokia.com.
    3838** $QT_END_LICENSE$
    3939**
     
    244244    quint32 glyphDataSize;
    245245    QString fileName;
     246    QByteArray encodedFileName;
    246247    bool readOnly;
    247248
  • trunk/src/gui/text/qfontengine_win.cpp

    r2 r561  
    22**
    33** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
    4 ** Contact: Qt Software Information (qt-info@nokia.com)
     4** All rights reserved.
     5** Contact: Nokia Corporation (qt-info@nokia.com)
    56**
    67** This file is part of the QtGui module of the Qt Toolkit.
     
    2122** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    2223**
    23 ** In addition, as a special exception, Nokia gives you certain
    24 ** additional rights. These rights are described in the Nokia Qt LGPL
    25 ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
    26 ** package.
     24** In addition, as a special exception, Nokia gives you certain additional
     25** rights.  These rights are described in the Nokia Qt LGPL Exception
     26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
    2727**
    2828** GNU General Public License Usage
     
    3434** met: http://www.gnu.org/copyleft/gpl.html.
    3535**
    36 ** If you are unsure which license is appropriate for your use, please
    37 ** contact the sales department at qt-sales@nokia.com.
     36** If you have questions regarding the use of this file, please contact
     37** Nokia at qt-info@nokia.com.
    3838** $QT_END_LICENSE$
    3939**
     
    4949#include <qpaintdevice.h>
    5050#include <qpainter.h>
    51 #include <qlibrary.h>
    5251#include <limits.h>
    5352
     
    6665#include <private/qnativeimage_p.h>
    6766
    68 #if defined(Q_OS_WINCE)
     67#if defined(Q_WS_WINCE)
    6968#include "qguifunctions_wince.h"
    7069#endif
     
    8685   )
    8786
    88 typedef BOOL (WINAPI *PtrGetCharWidthI)(HDC, UINT, UINT, LPWORD, LPINT);
    89 
    9087// common DC for all fonts
    9188
     
    129126#endif
    130127
    131 static HFONT stock_sysfont  = 0;
    132 
     128#ifndef Q_WS_WINCE
     129typedef BOOL (WINAPI *PtrGetCharWidthI)(HDC, UINT, UINT, LPWORD, LPINT);
    133130static PtrGetCharWidthI ptrGetCharWidthI = 0;
    134131static bool resolvedGetCharWidthI = false;
     
    141138    ptrGetCharWidthI = (PtrGetCharWidthI)QLibrary::resolve(QLatin1String("gdi32"), "GetCharWidthI");
    142139}
    143 
    144 // Copy a LOGFONTW struct into a LOGFONTA by converting the face name to an 8 bit value.
    145 // This is needed when calling CreateFontIndirect on non-unicode windowses.
    146 inline static void wa_copy_logfont(LOGFONTW *lfw, LOGFONTA *lfa)
    147 {
    148     lfa->lfHeight = lfw->lfHeight;
    149     lfa->lfWidth = lfw->lfWidth;
    150     lfa->lfEscapement = lfw->lfEscapement;
    151     lfa->lfOrientation = lfw->lfOrientation;
    152     lfa->lfWeight = lfw->lfWeight;
    153     lfa->lfItalic = lfw->lfItalic;
    154     lfa->lfUnderline = lfw->lfUnderline;
    155     lfa->lfCharSet = lfw->lfCharSet;
    156     lfa->lfOutPrecision = lfw->lfOutPrecision;
    157     lfa->lfClipPrecision = lfw->lfClipPrecision;
    158     lfa->lfQuality = lfw->lfQuality;
    159     lfa->lfPitchAndFamily = lfw->lfPitchAndFamily;
    160 
    161     QString fam = QString::fromUtf16((const ushort*)lfw->lfFaceName);
    162     memcpy(lfa->lfFaceName, fam.toLocal8Bit().constData(), fam.length() + 1);
    163 }
     140#endif // !defined(Q_WS_WINCE)
    164141
    165142// defined in qtextengine_win.cpp
     
    188165}
    189166
    190 static inline HFONT systemFont()
    191 {
    192     if (stock_sysfont == 0)
    193         stock_sysfont = (HFONT)GetStockObject(SYSTEM_FONT);
    194     return stock_sysfont;
    195 }
    196 
    197 
    198167// general font engine
    199168
     
    206175}
    207176
    208 #if defined(Q_OS_WINCE)
    209 static OUTLINETEXTMETRICW *getOutlineTextMetric(HDC hdc)
     177static OUTLINETEXTMETRIC *getOutlineTextMetric(HDC hdc)
    210178{
    211179    int size;
    212     size = GetOutlineTextMetricsW(hdc, 0, 0);
    213     OUTLINETEXTMETRICW *otm = (OUTLINETEXTMETRICW *)malloc(size);
    214     GetOutlineTextMetricsW(hdc, size, otm);
     180    size = GetOutlineTextMetrics(hdc, 0, 0);
     181    OUTLINETEXTMETRIC *otm = (OUTLINETEXTMETRIC *)malloc(size);
     182    GetOutlineTextMetrics(hdc, size, otm);
    215183    return otm;
    216184}
    217 #else
    218 static OUTLINETEXTMETRICA *getOutlineTextMetric(HDC hdc)
    219 {
    220     int size;
    221     size = GetOutlineTextMetricsA(hdc, 0, 0);
    222     OUTLINETEXTMETRICA *otm = (OUTLINETEXTMETRICA *)malloc(size);
    223     GetOutlineTextMetricsA(hdc, size, otm);
    224     return otm;
    225 }
    226 #endif
    227185
    228186void QFontEngineWin::getCMap()
    229187{
    230     QT_WA({
    231         ttf = (bool)(tm.w.tmPitchAndFamily & TMPF_TRUETYPE);
    232     } , {
    233         ttf = (bool)(tm.a.tmPitchAndFamily & TMPF_TRUETYPE);
    234     });
     188    ttf = (bool)(tm.tmPitchAndFamily & TMPF_TRUETYPE);
    235189    HDC hdc = shared_dc();
    236190    SelectObject(hdc, hfont);
     
    250204    _faceId.index = 0;
    251205    if(cmap) {
    252 #if defined(Q_OS_WINCE)
    253         OUTLINETEXTMETRICW *otm = getOutlineTextMetric(hdc);
    254 #else
    255         OUTLINETEXTMETRICA *otm = getOutlineTextMetric(hdc);
    256 #endif
     206        OUTLINETEXTMETRIC *otm = getOutlineTextMetric(hdc);
    257207        designToDevice = QFixed((int)otm->otmEMSquare)/int(otm->otmTextMetrics.tmHeight);
    258208        unitsPerEm = otm->otmEMSquare;
    259209        x_height = (int)otm->otmsXHeight;
    260210        loadKerningPairs(designToDevice);
    261         _faceId.filename = (char *)otm + (int)otm->otmpFullName;
     211        _faceId.filename = QString::fromWCharArray((wchar_t *)((char *)otm + (int)otm->otmpFullName)).toLatin1();
    262212        lineWidth = otm->otmsUnderscoreSize;
    263213        fsType = otm->otmfsType;
    264214        free(otm);
    265215    } else {
    266         unitsPerEm = tm.w.tmHeight;
     216        unitsPerEm = tm.tmHeight;
    267217    }
    268218}
     
    287237    int glyph_pos = 0;
    288238    if (mirrored) {
    289 #if defined(Q_OS_WINCE)
     239#if defined(Q_WS_WINCE)
    290240        {
    291241#else
     
    304254        } else {
    305255#endif
    306             ushort first, last;
    307             QT_WA({
    308                 first = tm.w.tmFirstChar;
    309                 last = tm.w.tmLastChar;
    310             }, {
    311                 first = tm.a.tmFirstChar;
    312                 last = tm.a.tmLastChar;
    313             });
     256            wchar_t first = tm.tmFirstChar;
     257            wchar_t last = tm.tmLastChar;
     258
    314259            for (; i < numChars; ++i, ++glyph_pos) {
    315260                uint ucs = QChar::mirroredChar(getChar(str, i, numChars));
    316261                if (
    317 #ifdef Q_OS_WINCE
    318                     tm.w.tmFirstChar > 60000 || // see line 375
     262#ifdef Q_WS_WINCE
     263                    tm.tmFirstChar > 60000 || // see line 375
    319264#endif
    320265                        ucs >= first && ucs <= last)
     
    325270        }
    326271    } else {
    327 #if defined(Q_OS_WINCE)
     272#if defined(Q_WS_WINCE)
    328273        {
    329274#else
     
    342287        } else {
    343288#endif
    344             ushort first, last;
    345             QT_WA({
    346                 first = tm.w.tmFirstChar;
    347                 last = tm.w.tmLastChar;
    348             }, {
    349                 first = tm.a.tmFirstChar;
    350                 last = tm.a.tmLastChar;
    351             });
     289            wchar_t first = tm.tmFirstChar;
     290            wchar_t last = tm.tmLastChar;
     291
    352292            for (; i < numChars; ++i, ++glyph_pos) {
    353293                uint uc = getChar(str, i, numChars);
    354294                if (
    355 #ifdef Q_OS_WINCE
    356                     tm.w.tmFirstChar > 60000 || // see comment in QFontEngineWin
     295#ifdef Q_WS_WINCE
     296                    tm.tmFirstChar > 60000 || // see comment in QFontEngineWin
    357297#endif
    358298                        uc >= first && uc <= last)
     
    388328    x_height = -1;
    389329
    390     BOOL res;
    391     QT_WA({
    392         res = GetTextMetricsW(hdc, &tm.w);
    393     } , {
    394         res = GetTextMetricsA(hdc, &tm.a);
    395     });
    396     fontDef.fixedPitch = !(tm.w.tmPitchAndFamily & TMPF_FIXED_PITCH);
    397     if (!res)
     330    BOOL res = GetTextMetrics(hdc, &tm);
     331    fontDef.fixedPitch = !(tm.tmPitchAndFamily & TMPF_FIXED_PITCH);
     332    if (!res) {
    398333        qErrnoWarning("QFontEngineWin: GetTextMetrics failed");
    399 
    400     cache_cost = tm.w.tmHeight * tm.w.tmAveCharWidth * 2000;
     334        ZeroMemory(&tm, sizeof(TEXTMETRIC));
     335    }
     336
     337    cache_cost = tm.tmHeight * tm.tmAveCharWidth * 2000;
    401338    getCMap();
    402339
    403     useTextOutA = false;
    404 #ifndef Q_OS_WINCE
    405     // TextOutW doesn't work for symbol fonts on Windows 95!
    406     // since we're using glyph indices we don't care for ttfs about this!
    407     if (QSysInfo::WindowsVersion == QSysInfo::WV_95 && !ttf &&
    408          (_name == QLatin1String("Marlett") || _name == QLatin1String("Symbol") ||
    409            _name == QLatin1String("Webdings") || _name == QLatin1String("Wingdings")))
    410             useTextOutA = true;
    411 #endif
    412340    widthCache = 0;
    413341    widthCacheSize = 0;
     
    415343    designAdvancesSize = 0;
    416344
     345#ifndef Q_WS_WINCE
    417346    if (!resolvedGetCharWidthI)
    418347        resolveGetCharWidthI();
     348#endif
    419349}
    420350
     
    428358
    429359    // make sure we aren't by accident still selected
    430     SelectObject(shared_dc(), systemFont());
     360    SelectObject(shared_dc(), (HFONT)GetStockObject(SYSTEM_FONT));
    431361
    432362    if (!stockFont) {
     
    436366}
    437367
    438 HGDIOBJ QFontEngineWin::selectDesignFont(QFixed *overhang) const
     368HGDIOBJ QFontEngineWin::selectDesignFont() const
    439369{
    440370    LOGFONT f = logfont;
    441371    f.lfHeight = unitsPerEm;
    442     HFONT designFont;
    443     QT_WA({
    444         designFont = CreateFontIndirectW(&f);
    445     }, {
    446         LOGFONTA fa;
    447         wa_copy_logfont(&f, &fa);
    448         designFont = CreateFontIndirectA(&fa);
    449     });
    450     HGDIOBJ oldFont = SelectObject(shared_dc(), designFont);
    451 
    452     if (QSysInfo::WindowsVersion & QSysInfo::WV_DOS_based) {
    453         BOOL res;
    454         QT_WA({
    455             TEXTMETRICW tm;
    456             res = GetTextMetricsW(shared_dc(), &tm);
    457             if (!res)
    458                 qErrnoWarning("QFontEngineWin: GetTextMetrics failed");
    459             *overhang = QFixed((int)tm.tmOverhang) / designToDevice;
    460         } , {
    461             TEXTMETRICA tm;
    462             res = GetTextMetricsA(shared_dc(), &tm);
    463             if (!res)
    464                 qErrnoWarning("QFontEngineWin: GetTextMetrics failed");
    465             *overhang = QFixed((int)tm.tmOverhang) / designToDevice;
    466         });
    467     } else {
    468         *overhang = 0;
    469     }
    470     return oldFont;
     372    HFONT designFont = CreateFontIndirect(&f);
     373    return SelectObject(shared_dc(), designFont);
    471374}
    472375
     
    483386        return true;
    484387
    485 #if defined(Q_OS_WINCE)
    486     HDC hdc = shared_dc();
    487     if (flags & QTextEngine::DesignMetrics) {
    488         HGDIOBJ oldFont = 0;
    489         QFixed overhang = 0;
    490 
    491         int glyph_pos = 0;
    492         for(register int i = 0; i < len; i++) {
    493             bool surrogate = (str[i].unicode() >= 0xd800 && str[i].unicode() < 0xdc00 && i < len-1
    494                               && str[i+1].unicode() >= 0xdc00 && str[i+1].unicode() < 0xe000);
    495             unsigned int glyph = glyphs->glyphs[glyph_pos];
    496             if(int(glyph) >= designAdvancesSize) {
    497                 int newSize = (glyph + 256) >> 8 << 8;
    498                 designAdvances = (QFixed *)realloc(designAdvances, newSize*sizeof(QFixed));
    499                 for(int i = designAdvancesSize; i < newSize; ++i)
    500                     designAdvances[i] = -1000000;
    501                 designAdvancesSize = newSize;
    502             }
    503             if(designAdvances[glyph] < -999999) {
    504                 if(!oldFont)
    505                     oldFont = selectDesignFont(&overhang);
    506                 SIZE size = {0, 0};
    507                 GetTextExtentPoint32W(hdc, (wchar_t *)(str+i), surrogate ? 2 : 1, &size);
    508                 designAdvances[glyph] = QFixed((int)size.cx)/designToDevice;
    509             }
    510             glyphs->advances_x[glyph_pos] = designAdvances[glyph];
    511             glyphs->advances_y[glyph_pos] = 0;
    512             if (surrogate)
    513                 ++i;
    514             ++glyph_pos;
    515         }
    516         if(oldFont)
    517             DeleteObject(SelectObject(hdc, oldFont));
    518     } else {
    519         int glyph_pos = 0;
    520         HGDIOBJ oldFont = 0;
    521 
    522         for(register int i = 0; i < len; i++) {
    523             bool surrogate = (str[i].unicode() >= 0xd800 && str[i].unicode() < 0xdc00 && i < len-1
    524                               && str[i+1].unicode() >= 0xdc00 && str[i+1].unicode() < 0xe000);
    525             unsigned int glyph = glyphs->glyphs[glyph_pos];
    526 
    527             glyphs->advances_y[glyph_pos] = 0;
    528 
    529             if (glyph >= widthCacheSize) {
    530                 int newSize = (glyph + 256) >> 8 << 8;
    531                 widthCache = (unsigned char *)realloc(widthCache, newSize*sizeof(QFixed));
    532                 memset(widthCache + widthCacheSize, 0, newSize - widthCacheSize);
    533                 widthCacheSize = newSize;
    534             }
    535             glyphs->advances_x[glyph_pos] = widthCache[glyph];
    536             // font-width cache failed
    537             if (glyphs->advances_x[glyph_pos] == 0) {
    538                 SIZE size = {0, 0};
    539                 if (!oldFont)
    540                     oldFont = SelectObject(hdc, hfont);
    541                 GetTextExtentPoint32W(hdc, (wchar_t *)str + i, surrogate ? 2 : 1, &size);
    542                 glyphs->advances_x[glyph_pos] = size.cx;
    543                 // if glyph's within cache range, store it for later
    544                 if (size.cx > 0 && size.cx < 0x100)
    545                     widthCache[glyph] = size.cx;
    546             }
    547 
    548             if (surrogate)
    549                 ++i;
    550             ++glyph_pos;
    551         }
    552 
    553         if (oldFont)
    554             SelectObject(hdc, oldFont);
    555     }
     388    recalcAdvances(glyphs, flags);
     389    return true;
     390}
     391
     392inline void calculateTTFGlyphWidth(HDC hdc, UINT glyph, int &width)
     393{
     394#if defined(Q_WS_WINCE)
     395    GetCharWidth32(hdc, glyph, glyph, &width);
    556396#else
    557     recalcAdvances(glyphs, flags);
    558 #endif
    559     return true;
     397    if (ptrGetCharWidthI)
     398        ptrGetCharWidthI(hdc, glyph, 1, 0, &width);
     399#endif
    560400}
    561401
     
    565405    HDC hdc = shared_dc();
    566406    if (ttf && (flags & QTextEngine::DesignMetrics)) {
    567         QFixed overhang = 0;
    568 
    569407        for(int i = 0; i < glyphs->numGlyphs; i++) {
    570408            unsigned int glyph = glyphs->glyphs[i];
    571409            if(int(glyph) >= designAdvancesSize) {
    572410                int newSize = (glyph + 256) >> 8 << 8;
    573                 designAdvances = (QFixed *)realloc(designAdvances, newSize*sizeof(QFixed));
     411                designAdvances = q_check_ptr((QFixed *)realloc(designAdvances,
     412                            newSize*sizeof(QFixed)));
    574413                for(int i = designAdvancesSize; i < newSize; ++i)
    575414                    designAdvances[i] = -1000000;
    576415                designAdvancesSize = newSize;
    577416            }
    578             if(designAdvances[glyph] < -999999) {
    579                 if(!oldFont)
    580                     oldFont = selectDesignFont(&overhang);
    581 
    582                 if (ptrGetCharWidthI) {
    583                     int width = 0;
    584                     ptrGetCharWidthI(hdc, glyph, 1, 0, &width);
    585 
    586                     designAdvances[glyph] = QFixed(width) / designToDevice;
    587                 } else {
    588 #ifndef Q_OS_WINCE
    589                     GLYPHMETRICS gm;
    590                     DWORD res = GDI_ERROR;
    591                     MAT2 mat;
    592                     mat.eM11.value = mat.eM22.value = 1;
    593                     mat.eM11.fract = mat.eM22.fract = 0;
    594                     mat.eM21.value = mat.eM12.value = 0;
    595                     mat.eM21.fract = mat.eM12.fract = 0;
    596                     QT_WA({
    597                         res = GetGlyphOutlineW(hdc, glyph, GGO_METRICS|GGO_GLYPH_INDEX|GGO_NATIVE, &gm, 0, 0, &mat);
    598                     } , {
    599                         res = GetGlyphOutlineA(hdc, glyph, GGO_METRICS|GGO_GLYPH_INDEX|GGO_NATIVE, &gm, 0, 0, &mat);
    600                     });
    601 
    602                     if (res != GDI_ERROR) {
    603                         designAdvances[glyph] = QFixed(gm.gmCellIncX) / designToDevice;
    604                     }
    605 #endif
    606                 }
     417            if (designAdvances[glyph] < -999999) {
     418                if (!oldFont)
     419                    oldFont = selectDesignFont();
     420
     421                int width = 0;
     422                calculateTTFGlyphWidth(hdc, glyph, width);
     423                designAdvances[glyph] = QFixed(width) / designToDevice;
    607424            }
    608425            glyphs->advances_x[i] = designAdvances[glyph];
     
    612429            DeleteObject(SelectObject(hdc, oldFont));
    613430    } else {
    614         int overhang = (QSysInfo::WindowsVersion & QSysInfo::WV_DOS_based) ? tm.a.tmOverhang : 0;
    615 
    616431        for(int i = 0; i < glyphs->numGlyphs; i++) {
    617432            unsigned int glyph = glyphs->glyphs[i];
     
    621436            if (glyph >= widthCacheSize) {
    622437                int newSize = (glyph + 256) >> 8 << 8;
    623                 widthCache = (unsigned char *)realloc(widthCache, newSize*sizeof(QFixed));
     438                widthCache = q_check_ptr((unsigned char *)realloc(widthCache,
     439                            newSize*sizeof(QFixed)));
    624440                memset(widthCache + widthCacheSize, 0, newSize - widthCacheSize);
    625441                widthCacheSize = newSize;
     
    641457                    }
    642458                    SIZE size = {0, 0};
    643                     GetTextExtentPoint32W(hdc, (wchar_t *)ch, chrLen, &size);
     459                    GetTextExtentPoint32(hdc, (wchar_t *)ch, chrLen, &size);
    644460                    width = size.cx;
    645                 } else if (ptrGetCharWidthI) {
    646                     ptrGetCharWidthI(hdc, glyph, 1, 0, &width);
    647 
    648                     width -= overhang;
    649461                } else {
    650 #ifndef Q_OS_WINCE
    651                     GLYPHMETRICS gm;
    652                     DWORD res = GDI_ERROR;
    653                     MAT2 mat;
    654                     mat.eM11.value = mat.eM22.value = 1;
    655                     mat.eM11.fract = mat.eM22.fract = 0;
    656                     mat.eM21.value = mat.eM12.value = 0;
    657                     mat.eM21.fract = mat.eM12.fract = 0;
    658                     QT_WA({
    659                         res = GetGlyphOutlineW(hdc, glyph, GGO_METRICS|GGO_GLYPH_INDEX, &gm, 0, 0, &mat);
    660                     } , {
    661                         res = GetGlyphOutlineA(hdc, glyph, GGO_METRICS|GGO_GLYPH_INDEX, &gm, 0, 0, &mat);
    662                     });
    663 
    664                     if (res != GDI_ERROR) {
    665                         width = gm.gmCellIncX;
    666                     }
    667 #endif
     462                    calculateTTFGlyphWidth(hdc, glyph, width);
    668463                }
    669464                glyphs->advances_x[i] = width;
     
    688483        w += glyphs.effectiveAdvance(i);
    689484
    690     return glyph_metrics_t(0, -tm.w.tmAscent, w, tm.w.tmHeight, w, 0);
    691 }
    692 
    693 
    694 
    695 
    696 #ifndef Q_OS_WINCE
    697 typedef HRESULT (WINAPI *pGetCharABCWidthsFloat)(HDC, UINT, UINT, LPABCFLOAT);
    698 static pGetCharABCWidthsFloat qt_GetCharABCWidthsFloat = 0;
     485    return glyph_metrics_t(0, -tm.tmAscent, w, tm.tmHeight, w, 0);
     486}
     487
     488#ifndef Q_WS_WINCE
     489bool QFontEngineWin::getOutlineMetrics(glyph_t glyph, const QTransform &t, glyph_metrics_t *metrics) const
     490{
     491    Q_ASSERT(metrics != 0);
     492
     493    HDC hdc = shared_dc();
     494
     495    GLYPHMETRICS gm;
     496    DWORD res = 0;
     497    MAT2 mat;
     498    mat.eM11.value = mat.eM22.value = 1;
     499    mat.eM11.fract = mat.eM22.fract = 0;
     500    mat.eM21.value = mat.eM12.value = 0;
     501    mat.eM21.fract = mat.eM12.fract = 0;
     502
     503    if (t.type() > QTransform::TxTranslate) {
     504        // We need to set the transform using the HDC's world
     505        // matrix rather than using the MAT2 above, because the
     506        // results provided when transforming via MAT2 does not
     507        // match the glyphs that are drawn using a WorldTransform
     508        XFORM xform;
     509        xform.eM11 = t.m11();
     510        xform.eM12 = t.m12();
     511        xform.eM21 = t.m21();
     512        xform.eM22 = t.m22();
     513        xform.eDx = 0;
     514        xform.eDy = 0;
     515        SetGraphicsMode(hdc, GM_ADVANCED);
     516        SetWorldTransform(hdc, &xform);
     517    }
     518
     519    uint format = GGO_METRICS;
     520    if (ttf)
     521        format |= GGO_GLYPH_INDEX;
     522    res = GetGlyphOutline(hdc, glyph, format, &gm, 0, 0, &mat);
     523
     524    if (t.type() > QTransform::TxTranslate) {
     525        XFORM xform;
     526        xform.eM11 = xform.eM22 = 1;
     527        xform.eM12 = xform.eM21 = xform.eDx = xform.eDy = 0;
     528        SetWorldTransform(hdc, &xform);
     529        SetGraphicsMode(hdc, GM_COMPATIBLE);
     530    }
     531
     532    if (res != GDI_ERROR) {
     533        *metrics = glyph_metrics_t(gm.gmptGlyphOrigin.x, -gm.gmptGlyphOrigin.y,
     534                                  (int)gm.gmBlackBoxX, (int)gm.gmBlackBoxY, gm.gmCellIncX, gm.gmCellIncY);
     535        return true;
     536    } else {
     537        return false;
     538    }
     539}
    699540#endif
    700541
    701542glyph_metrics_t QFontEngineWin::boundingBox(glyph_t glyph, const QTransform &t)
    702543{
    703 #ifndef Q_OS_WINCE
    704     GLYPHMETRICS gm;
    705 
     544#ifndef Q_WS_WINCE
    706545    HDC hdc = shared_dc();
    707546    SelectObject(hdc, hfont);
    708     if(!ttf) {
    709         SIZE s = {0, 0};
    710         WCHAR ch = glyph;
    711         int width;
    712         int overhang = 0;
    713         static bool resolved = false;
    714         if (!resolved) {
    715             QLibrary lib(QLatin1String("gdi32"));
    716             qt_GetCharABCWidthsFloat = (pGetCharABCWidthsFloat) lib.resolve("GetCharABCWidthsFloatW");
    717             resolved = true;
    718         }
    719         if (QT_WA_INLINE(true, false) && qt_GetCharABCWidthsFloat) {
    720             ABCFLOAT abc;
    721             qt_GetCharABCWidthsFloat(hdc, ch, ch, &abc);
    722             width = qRound(abc.abcfB);
    723         } else {
    724             GetTextExtentPoint32W(hdc, &ch, 1, &s);
    725             overhang = (QSysInfo::WindowsVersion & QSysInfo::WV_DOS_based) ? tm.a.tmOverhang : 0;
    726             width = s.cx;
    727         }
    728 
    729         return glyph_metrics_t(0, -tm.a.tmAscent,
    730                                width, tm.a.tmHeight,
    731                                width-overhang, 0).transformed(t);
    732     } else {
    733         DWORD res = 0;
    734         MAT2 mat;
    735         mat.eM11.value = mat.eM22.value = 1;
    736         mat.eM11.fract = mat.eM22.fract = 0;
    737         mat.eM21.value = mat.eM12.value = 0;
    738         mat.eM21.fract = mat.eM12.fract = 0;
    739 
    740         if (t.type() > QTransform::TxTranslate) {
    741             // We need to set the transform using the HDC's world
    742             // matrix rather than using the MAT2 above, because the
    743             // results provided when transforming via MAT2 does not
    744             // match the glyphs that are drawn using a WorldTransform
    745             XFORM xform;
    746             xform.eM11 = t.m11();
    747             xform.eM12 = t.m12();
    748             xform.eM21 = t.m21();
    749             xform.eM22 = t.m22();
    750             xform.eDx = 0;
    751             xform.eDy = 0;
    752             SetGraphicsMode(hdc, GM_ADVANCED);
    753             SetWorldTransform(hdc, &xform);
    754         }
    755 
    756         QT_WA({
    757             res = GetGlyphOutlineW(hdc, glyph, GGO_METRICS|GGO_GLYPH_INDEX, &gm, 0, 0, &mat);
    758         } , {
    759             res = GetGlyphOutlineA(hdc, glyph, GGO_METRICS|GGO_GLYPH_INDEX, &gm, 0, 0, &mat);
    760         });
    761         if (t.type() > QTransform::TxTranslate) {
    762             XFORM xform;
    763             xform.eM11 = xform.eM22 = 1;
    764             xform.eM12 = xform.eM21 = xform.eDx = xform.eDy = 0;
    765             SetWorldTransform(hdc, &xform);
    766             SetGraphicsMode(hdc, GM_COMPATIBLE);
    767         }
    768 
    769         if (res != GDI_ERROR) {
    770             return glyph_metrics_t(gm.gmptGlyphOrigin.x, -gm.gmptGlyphOrigin.y,
    771                                   (int)gm.gmBlackBoxX, (int)gm.gmBlackBoxY, gm.gmCellIncX, gm.gmCellIncY);
    772         }
    773     }
    774     return glyph_metrics_t();
     547
     548    glyph_metrics_t glyphMetrics;
     549    bool success = getOutlineMetrics(glyph, t, &glyphMetrics);
     550
     551    if (!ttf && !success) {
     552        // Bitmap fonts
     553        wchar_t ch = glyph;
     554        ABCFLOAT abc;
     555        GetCharABCWidthsFloat(hdc, ch, ch, &abc);
     556        int width = qRound(abc.abcfB);
     557
     558        return glyph_metrics_t(QFixed::fromReal(abc.abcfA), -tm.tmAscent, width, tm.tmHeight, width, 0).transformed(t);
     559    }
     560
     561    return glyphMetrics;
    775562#else
    776563    HDC hdc = shared_dc();
     
    794581#endif
    795582    {   // fallback
    796         width = tm.w.tmMaxCharWidth;
     583        width = tm.tmMaxCharWidth;
    797584        advance = width;
    798585    }
    799586
    800587    SelectObject(hdc, oldFont);
    801     return glyph_metrics_t(0, -tm.w.tmAscent, width, tm.w.tmHeight, advance, 0).transformed(t);
     588    return glyph_metrics_t(0, -tm.tmAscent, width, tm.tmHeight, advance, 0).transformed(t);
    802589#endif
    803590}
     
    805592QFixed QFontEngineWin::ascent() const
    806593{
    807     return tm.w.tmAscent;
     594    return tm.tmAscent;
    808595}
    809596
    810597QFixed QFontEngineWin::descent() const
    811598{
    812     return tm.w.tmDescent;
     599    // ### we substract 1 to even out the historical +1 in QFontMetrics's
     600    // ### height=asc+desc+1 equation. Fix in Qt5.
     601    return tm.tmDescent - 1;
    813602}
    814603
    815604QFixed QFontEngineWin::leading() const
    816605{
    817     return tm.w.tmExternalLeading;
     606    return tm.tmExternalLeading;
    818607}
    819608
     
    828617QFixed QFontEngineWin::averageCharWidth() const
    829618{
    830     return tm.w.tmAveCharWidth;
     619    return tm.tmAveCharWidth;
    831620}
    832621
    833622qreal QFontEngineWin::maxCharWidth() const
    834623{
    835     return tm.w.tmMaxCharWidth;
     624    return tm.tmMaxCharWidth;
    836625}
    837626
     
    872661qreal QFontEngineWin::minRightBearing() const
    873662{
    874 #ifdef Q_OS_WINCE
     663#ifdef Q_WS_WINCE
    875664    if (rbearing == SHRT_MIN) {
    876665        int ml = 0;
     
    880669        if (ttf) {
    881670            ABC *abc = 0;
    882             int n = QT_WA_INLINE(tm.w.tmLastChar - tm.w.tmFirstChar, tm.a.tmLastChar - tm.a.tmFirstChar);
     671            int n = tm.tmLastChar - tm.tmFirstChar;
    883672            if (n <= max_font_count) {
    884673                abc = new ABC[n+1];
    885                 GetCharABCWidths(hdc, tm.w.tmFirstChar, tm.w.tmLastChar, abc);
     674                GetCharABCWidths(hdc, tm.tmFirstChar, tm.tmLastChar, abc);
    886675            } else {
    887676                abc = new ABC[char_table_entries+1];
     
    899688            }
    900689            delete [] abc;
    901         } else {
    902             ml = 0;
    903             mr = -tm.a.tmOverhang;
    904690        }
    905691        lbearing = ml;
     
    916702        if (ttf) {
    917703            ABC *abc = 0;
    918             int n = QT_WA_INLINE(tm.w.tmLastChar - tm.w.tmFirstChar, tm.a.tmLastChar - tm.a.tmFirstChar);
     704            int n = tm.tmLastChar - tm.tmFirstChar;
    919705            if (n <= max_font_count) {
    920706                abc = new ABC[n+1];
    921                 QT_WA({
    922                     GetCharABCWidths(hdc, tm.w.tmFirstChar, tm.w.tmLastChar, abc);
    923                 }, {
    924                     GetCharABCWidthsA(hdc,tm.a.tmFirstChar,tm.a.tmLastChar,abc);
    925                 });
     707                GetCharABCWidths(hdc, tm.tmFirstChar, tm.tmLastChar, abc);
    926708            } else {
    927709                abc = new ABC[char_table_entries+1];
    928                 QT_WA({
    929                     for(int i = 0; i < char_table_entries; i++)
    930                         GetCharABCWidths(hdc, char_table[i], char_table[i], abc+i);
    931                 }, {
    932                     for(int i = 0; i < char_table_entries; i++) {
    933                         QByteArray w = QString(QChar(char_table[i])).toLocal8Bit();
    934                         if (w.length() == 1) {
    935                             uint ch8 = (uchar)w[0];
    936                             GetCharABCWidthsA(hdc, ch8, ch8, abc+i);
    937                         }
    938                     }
    939                 });
     710                for(int i = 0; i < char_table_entries; i++)
     711                    GetCharABCWidths(hdc, char_table[i], char_table[i], abc + i);
    940712                n = char_table_entries;
    941713            }
     
    950722            delete [] abc;
    951723        } else {
    952             QT_WA({
    953                 ABCFLOAT *abc = 0;
    954                 int n = tm.w.tmLastChar - tm.w.tmFirstChar+1;
    955                 if (n <= max_font_count) {
    956                     abc = new ABCFLOAT[n];
    957                     GetCharABCWidthsFloat(hdc, tm.w.tmFirstChar, tm.w.tmLastChar, abc);
    958                 } else {
    959                     abc = new ABCFLOAT[char_table_entries];
    960                     for(int i = 0; i < char_table_entries; i++)
    961                         GetCharABCWidthsFloat(hdc, char_table[i], char_table[i], abc+i);
    962                     n = char_table_entries;
     724            ABCFLOAT *abc = 0;
     725            int n = tm.tmLastChar - tm.tmFirstChar+1;
     726            if (n <= max_font_count) {
     727                abc = new ABCFLOAT[n];
     728                GetCharABCWidthsFloat(hdc, tm.tmFirstChar, tm.tmLastChar, abc);
     729            } else {
     730                abc = new ABCFLOAT[char_table_entries];
     731                for(int i = 0; i < char_table_entries; i++)
     732                    GetCharABCWidthsFloat(hdc, char_table[i], char_table[i], abc+i);
     733                n = char_table_entries;
     734            }
     735            float fml = abc[0].abcfA;
     736            float fmr = abc[0].abcfC;
     737            for (int i=1; i<n; i++) {
     738                if (abc[i].abcfA + abc[i].abcfB + abc[i].abcfC != 0) {
     739                    fml = qMin(fml,abc[i].abcfA);
     740                    fmr = qMin(fmr,abc[i].abcfC);
    963741                }
    964                 float fml = abc[0].abcfA;
    965                 float fmr = abc[0].abcfC;
    966                 for (int i=1; i<n; i++) {
    967                     if (abc[i].abcfA + abc[i].abcfB + abc[i].abcfC != 0) {
    968                         fml = qMin(fml,abc[i].abcfA);
    969                         fmr = qMin(fmr,abc[i].abcfC);
    970                     }
    971                 }
    972                 ml = int(fml-0.9999);
    973                 mr = int(fmr-0.9999);
    974                 delete [] abc;
    975             } , {
    976                 ml = 0;
    977                 mr = -tm.a.tmOverhang;
    978             });
     742            }
     743            ml = int(fml - 0.9999);
     744            mr = int(fmr - 0.9999);
     745            delete [] abc;
    979746        }
    980747        lbearing = ml;
     
    1013780        }
    1014781    } else {
    1015         QT_WA({
    1016             while(len--) {
    1017                 if (tm.w.tmFirstChar > string->unicode() || tm.w.tmLastChar < string->unicode())
    1018                     return false;
    1019             }
    1020         }, {
    1021             while(len--) {
    1022                 if (tm.a.tmFirstChar > string->unicode() || tm.a.tmLastChar < string->unicode())
    1023                     return false;
    1024             }
    1025         });
     782        while(len--) {
     783            if (tm.tmFirstChar > string->unicode() || tm.tmLastChar < string->unicode())
     784                return false;
     785        }
    1026786    }
    1027787    return true;
     
    1048808                           QPainterPath *path, bool ttf, glyph_metrics_t *metric = 0, qreal scale = 1)
    1049809{
    1050 #if defined(Q_OS_WINCE)
     810#if defined(Q_WS_WINCE)
    1051811    Q_UNUSED(glyph);
    1052812    Q_UNUSED(hdc);
     
    1065825    memset(&gMetric, 0, sizeof(GLYPHMETRICS));
    1066826    int bufferSize = GDI_ERROR;
    1067 #if !defined(Q_OS_WINCE)
    1068     QT_WA( {
    1069         bufferSize = GetGlyphOutlineW(hdc, glyph, glyphFormat, &gMetric, 0, 0, &mat);
    1070     }, {
    1071         bufferSize = GetGlyphOutlineA(hdc, glyph, glyphFormat, &gMetric, 0, 0, &mat);
    1072     });
     827#if !defined(Q_WS_WINCE)
     828    bufferSize = GetGlyphOutline(hdc, glyph, glyphFormat, &gMetric, 0, 0, &mat);
    1073829#endif
    1074830    if ((DWORD)bufferSize == GDI_ERROR) {
     
    1078834    void *dataBuffer = new char[bufferSize];
    1079835    DWORD ret = GDI_ERROR;
    1080 #if !defined(Q_OS_WINCE)
    1081     QT_WA( {
    1082         ret = GetGlyphOutlineW(hdc, glyph, glyphFormat, &gMetric, bufferSize,
    1083                             dataBuffer, &mat);
    1084     }, {
    1085         ret = GetGlyphOutlineA(hdc, glyph, glyphFormat, &gMetric, bufferSize,
    1086                                 dataBuffer, &mat);
    1087     } );
     836#if !defined(Q_WS_WINCE)
     837    ret = GetGlyphOutline(hdc, glyph, glyphFormat, &gMetric, bufferSize, dataBuffer, &mat);
    1088838#endif
    1089839    if (ret == GDI_ERROR) {
     
    1172922    lf.lfHeight = -unitsPerEm;
    1173923    lf.lfWidth = 0;
    1174     HFONT hf;
    1175     QT_WA({
    1176         hf = CreateFontIndirectW(&lf);
    1177     }, {
    1178         LOGFONTA lfa;
    1179         wa_copy_logfont(&lf, &lfa);
    1180         hf = CreateFontIndirectA(&lfa);
    1181     });
     924    HFONT hf = CreateFontIndirect(&lf);
    1182925    HDC hdc = shared_dc();
    1183926    HGDIOBJ oldfont = SelectObject(hdc, hf);
     
    1200943                                      QPainterPath *path, QTextItem::RenderFlags flags)
    1201944{
    1202 #if !defined(Q_OS_WINCE)
    1203     if(tm.w.tmPitchAndFamily & (TMPF_TRUETYPE | TMPF_VECTOR)) {
     945#if !defined(Q_WS_WINCE)
     946    if(tm.tmPitchAndFamily & (TMPF_TRUETYPE | TMPF_VECTOR)) {
    1204947        hasOutline = true;
    1205948        QFontEngine::addOutlineToPath(x, y, glyphs, path, flags);
     
    1235978            GetFontData(hdc, HEAD, 44, &data, 4);
    1236979            USHORT macStyle = getUShort(data);
    1237             if (tm.w.tmItalic && !(macStyle & 2))
     980            if (tm.tmItalic && !(macStyle & 2))
    1238981                synthesized_flags = SynthesizedItalic;
    1239982            if (fontDef.stretch != 100 && ttf)
    1240983                synthesized_flags |= SynthesizedStretch;
    1241             if (tm.w.tmWeight >= 500 && !(macStyle & 1))
     984            if (tm.tmWeight >= 500 && !(macStyle & 1))
    1242985                synthesized_flags |= SynthesizedBold;
    1243986            //qDebug() << "font is" << _name <<
     
    1255998QFontEngine::Properties QFontEngineWin::properties() const
    1256999{
    1257 
    12581000    LOGFONT lf = logfont;
    12591001    lf.lfHeight = unitsPerEm;
    1260     HFONT hf;
    1261     QT_WA({
    1262         hf = CreateFontIndirectW(&lf);
    1263     }, {
    1264         LOGFONTA lfa;
    1265         wa_copy_logfont(&lf, &lfa);
    1266         hf = CreateFontIndirectA(&lfa);
    1267     });
     1002    HFONT hf = CreateFontIndirect(&lf);
    12681003    HDC hdc = shared_dc();
    12691004    HGDIOBJ oldfont = SelectObject(hdc, hf);
    1270 #if defined(Q_OS_WINCE)
    1271     OUTLINETEXTMETRICW *otm = getOutlineTextMetric(hdc);
    1272 #else
    1273     OUTLINETEXTMETRICA *otm = getOutlineTextMetric(hdc);
    1274 #endif
     1005    OUTLINETEXTMETRIC *otm = getOutlineTextMetric(hdc);
    12751006    Properties p;
    12761007    p.emSquare = unitsPerEm;
    12771008    p.italicAngle = otm->otmItalicAngle;
    1278     p.postscriptName = (char *)otm + (int)otm->otmpFamilyName;
    1279     p.postscriptName += (char *)otm + (int)otm->otmpStyleName;
     1009    p.postscriptName = QString::fromWCharArray((wchar_t *)((char *)otm + (int)otm->otmpFamilyName)).toLatin1();
     1010    p.postscriptName += QString::fromWCharArray((wchar_t *)((char *)otm + (int)otm->otmpStyleName)).toLatin1();
    12801011#ifndef QT_NO_PRINTER
    12811012    p.postscriptName = QPdf::stripSpecialCharacters(p.postscriptName);
     
    13021033        lf.lfItalic = false;
    13031034    lf.lfWidth = 0;
    1304     HFONT hf;
    1305     QT_WA({
    1306         hf = CreateFontIndirectW(&lf);
    1307     }, {
    1308         LOGFONTA lfa;
    1309         wa_copy_logfont(&lf, &lfa);
    1310         hf = CreateFontIndirectA(&lfa);
    1311     });
     1035    HFONT hf = CreateFontIndirect(&lf);
    13121036    HDC hdc = shared_dc();
    13131037    HGDIOBJ oldfont = SelectObject(hdc, hf);
     
    13341058#endif
    13351059
     1060extern bool qt_cleartype_enabled;
    13361061
    13371062QNativeImage *QFontEngineWin::drawGDIGlyph(HFONT font, glyph_t glyph, int margin,
    1338                                            const QTransform &t)
    1339 {
     1063                                           const QTransform &t, QImage::Format mask_format)
     1064{
     1065    Q_UNUSED(mask_format)
    13401066    glyph_metrics_t gm = boundingBox(glyph);
    13411067
     
    13521078    bool has_transformation = t.type() > QTransform::TxTranslate;
    13531079
    1354 #ifndef Q_OS_WINCE
     1080#ifndef Q_WS_WINCE
    13551081    unsigned int options = ttf ? ETO_GLYPH_INDEX : 0;
    13561082    XFORM xform;
     
    13771103        mat.eM11.value = mat.eM22.value = 1;
    13781104
    1379         int error = 0;
    1380         QT_WA( {
    1381                 error = GetGlyphOutlineW(hdc, glyph, ggo_options, &tgm, 0, 0, &mat);
    1382             }, {
    1383                 error = GetGlyphOutlineA(hdc, glyph, ggo_options, &tgm, 0, 0, &mat);
    1384             } );
    1385 
    1386         if (error == GDI_ERROR) {
     1105        if (GetGlyphOutline(hdc, glyph, ggo_options, &tgm, 0, 0, &mat) == GDI_ERROR) {
    13871106            qWarning("QWinFontEngine: unable to query transformed glyph metrics...");
    13881107            return 0;
     
    14071126#endif
    14081127
    1409     QNativeImage *ni = new QNativeImage(iw + 2 * margin,
    1410                                         ih + 2 * margin,
    1411                                         QNativeImage::systemFormat(), true);
     1128    QNativeImage *ni = new QNativeImage(iw + 2 * margin + 4,
     1129                                        ih + 2 * margin + 4,
     1130                                        QNativeImage::systemFormat(), !qt_cleartype_enabled);
     1131
     1132    /*If cleartype is enabled we use the standard system format even on Windows CE
     1133      and not the special textbuffer format we have to use if cleartype is disabled*/
     1134
    14121135    ni->image.fill(0xffffffff);
    14131136
     
    14261149        SetGraphicsMode(hdc, GM_ADVANCED);
    14271150        SetWorldTransform(hdc, &xform);
    1428         ExtTextOutW(hdc, 0, 0, options, 0, (LPCWSTR) &glyph, 1, 0);
     1151        ExtTextOut(hdc, 0, 0, options, 0, (LPCWSTR) &glyph, 1, 0);
    14291152    } else
    14301153#endif
    14311154    {
    1432         ExtTextOutW(hdc, -gx + margin, -gy + margin, options, 0, (LPCWSTR) &glyph, 1, 0);
    1433     }
    1434 
     1155        ExtTextOut(hdc, -gx + margin, -gy + margin, options, 0, (LPCWSTR) &glyph, 1, 0);
     1156    }
     1157   
    14351158    SelectObject(hdc, old_font);
    14361159    return ni;
     
    14381161
    14391162
    1440 extern bool qt_cleartype_enabled;
    14411163extern uint qt_pow_gamma[256];
    14421164
     
    14471169        LOGFONT lf = logfont;
    14481170        lf.lfQuality = ANTIALIASED_QUALITY;
    1449         font = CreateFontIndirectW(&lf);
    1450     }
    1451 
    1452     QNativeImage *mask = drawGDIGlyph(font, glyph, 0, xform);
     1171        font = CreateFontIndirect(&lf);
     1172    }
     1173    QImage::Format mask_format = QNativeImage::systemFormat();
     1174#ifndef Q_OS_WINCE
     1175    mask_format = QImage::Format_RGB32;
     1176#endif
     1177
     1178    QNativeImage *mask = drawGDIGlyph(font, glyph, 0, xform, mask_format);
    14531179    if (mask == 0)
    14541180        return QImage();
     
    14671193    for (int y=0; y<mask->height(); ++y) {
    14681194        uchar *dest = indexed.scanLine(y);
    1469         if (mask->systemFormat() == QImage::Format_RGB16) {
     1195        if (mask->image.format() == QImage::Format_RGB16) {
    14701196            const qint16 *src = (qint16 *) ((const QImage &) mask->image).scanLine(y);
    1471             for (int x=0; x<mask->width(); ++x) {
    1472 #ifdef Q_OS_WINCE
     1197            for (int x=0; x<mask->width(); ++x)
    14731198                dest[x] = 255 - qGray(src[x]);
    1474 #else
    1475                 dest[x] = 255 - (qt_pow_gamma[qGray(src[x])] * 255. / 2047.);
    1476 #endif
    1477             }
    14781199        } else {
    14791200            const uint *src = (uint *) ((const QImage &) mask->image).scanLine(y);
     
    14821203                dest[x] = 255 - qGray(src[x]);
    14831204#else
    1484                 dest[x] = 255 - (qt_pow_gamma[qGray(src[x])] * 255. / 2047.);
     1205                if (QNativeImage::systemFormat() == QImage::Format_RGB16)
     1206                    dest[x] = 255 - qGray(src[x]);
     1207                else
     1208                    dest[x] = 255 - (qt_pow_gamma[qGray(src[x])] * 255. / 2047.);
    14851209#endif
    14861210            }
     
    15081232    SystemParametersInfo(SPI_SETFONTSMOOTHINGCONTRAST, 0, (void *) 1000, 0);
    15091233
    1510     QNativeImage *mask = drawGDIGlyph(font, glyph, margin, t);
     1234    QNativeImage *mask = drawGDIGlyph(font, glyph, margin, t, QImage::Format_RGB32);
    15111235    SystemParametersInfo(SPI_SETFONTSMOOTHINGCONTRAST, 0, (void *) contrast, 0);
    15121236
     
    15521276
    15531277    LOGFONT lf = static_cast<QFontEngineWin *>(engines.at(0))->logfont;
    1554     HFONT hfont;
    1555     QT_WA({
    1556         memcpy(lf.lfFaceName, fam.utf16(), sizeof(TCHAR)*qMin(fam.length()+1,32));  // 32 = Windows hard-coded
    1557         hfont = CreateFontIndirectW(&lf);
    1558     } , {
    1559         // LOGFONTA and LOGFONTW are binary compatible
    1560         QByteArray lname = fam.toLocal8Bit();
    1561         memcpy(lf.lfFaceName,lname.data(),
    1562             qMin(lname.length()+1,32));  // 32 = Windows hard-coded
    1563         hfont = CreateFontIndirectA((LOGFONTA*)&lf);
    1564     });
     1278    memcpy(lf.lfFaceName, fam.utf16(), sizeof(wchar_t) * qMin(fam.length() + 1, 32));  // 32 = Windows hard-coded
     1279    HFONT hfont = CreateFontIndirect(&lf);
     1280
    15651281    bool stockFont = false;
    15661282    if (hfont == 0) {
  • trunk/src/gui/text/qfontengine_win_p.h

    r2 r561  
    22**
    33** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
    4 ** Contact: Qt Software Information (qt-info@nokia.com)
     4** All rights reserved.
     5** Contact: Nokia Corporation (qt-info@nokia.com)
    56**
    67** This file is part of the QtGui module of the Qt Toolkit.
     
    2122** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    2223**
    23 ** In addition, as a special exception, Nokia gives you certain
    24 ** additional rights. These rights are described in the Nokia Qt LGPL
    25 ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
    26 ** package.
     24** In addition, as a special exception, Nokia gives you certain additional
     25** rights.  These rights are described in the Nokia Qt LGPL Exception
     26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
    2727**
    2828** GNU General Public License Usage
     
    3434** met: http://www.gnu.org/copyleft/gpl.html.
    3535**
    36 ** If you are unsure which license is appropriate for your use, please
    37 ** contact the sales department at qt-sales@nokia.com.
     36** If you have questions regarding the use of this file, please contact
     37** Nokia at qt-info@nokia.com.
    3838** $QT_END_LICENSE$
    3939**
     
    8181                         QPainterPath *path, QTextItem::RenderFlags flags);
    8282
    83     HGDIOBJ selectDesignFont(QFixed *) const;
     83    HGDIOBJ selectDesignFont() const;
    8484
    8585    virtual glyph_metrics_t boundingBox(const QGlyphLayout &glyphs);
     
    110110    void getCMap();
    111111
    112     QString        _name;
    113     HFONT        hfont;
     112#ifndef Q_WS_WINCE
     113    bool getOutlineMetrics(glyph_t glyph, const QTransform &t, glyph_metrics_t *metrics) const;
     114#endif
     115
     116    QString     _name;
     117    HFONT       hfont;
    114118    LOGFONT     logfont;
    115     uint        stockFont   : 1;
    116     uint        useTextOutA : 1;
    117     uint        ttf         : 1;
     119    uint        stockFont  : 1;
     120    uint        ttf        : 1;
    118121    uint        hasOutline : 1;
    119     union {
    120         TEXTMETRICW        w;
    121         TEXTMETRICA        a;
    122     } tm;
    123     int                lw;
     122    TEXTMETRIC  tm;
     123    int         lw;
    124124    const unsigned char *cmap;
    125125    QByteArray cmapTable;
     
    139139
    140140private:
    141     QNativeImage *drawGDIGlyph(HFONT font, glyph_t, int margin, const QTransform &xform);
     141    QNativeImage *drawGDIGlyph(HFONT font, glyph_t, int margin, const QTransform &xform,
     142                               QImage::Format mask_format);
    142143
    143144};
  • trunk/src/gui/text/qfontengine_x11.cpp

    r2 r561  
    22**
    33** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
    4 ** Contact: Qt Software Information (qt-info@nokia.com)
     4** All rights reserved.
     5** Contact: Nokia Corporation (qt-info@nokia.com)
    56**
    67** This file is part of the QtGui module of the Qt Toolkit.
     
    2122** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    2223**
    23 ** In addition, as a special exception, Nokia gives you certain
    24 ** additional rights. These rights are described in the Nokia Qt LGPL
    25 ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
    26 ** package.
     24** In addition, as a special exception, Nokia gives you certain additional
     25** rights.  These rights are described in the Nokia Qt LGPL Exception
     26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
    2727**
    2828** GNU General Public License Usage
     
    3434** met: http://www.gnu.org/copyleft/gpl.html.
    3535**
    36 ** If you are unsure which license is appropriate for your use, please
    37 ** contact the sales department at qt-sales@nokia.com.
     36** If you have questions regarding the use of this file, please contact
     37** Nokia at qt-info@nokia.com.
    3838** $QT_END_LICENSE$
    3939**
     
    228228
    229229    for (QStringList::ConstIterator it = fontpath.constBegin(); it != fontpath.constEnd(); ++it) {
    230         if ((*it).left(1) != QLatin1String("/"))
     230        if (!(*it).startsWith(QLatin1Char('/')))
    231231            continue; // not a path name, a font server
    232232        QString fontmapname;
     
    489489            overall.x = qMin(overall.x, x);
    490490            overall.y = qMin(overall.y, y);
     491            // XCharStruct::rbearing is defined as distance from left edge to rightmost pixel
    491492            xmax = qMax(xmax, overall.xoff + glyphs.offsets[i].x + xcs->rbearing);
    492493            ymax = qMax(ymax, y + xcs->ascent + xcs->descent);
    493             overall.xoff += glyphs.advances_x[i];
     494            overall.xoff += glyphs.advances_x[i] + QFixed::fromFixed(glyphs.justifications[i].space_18d6);
    494495        } else {
    495496            QFixed size = _fs->ascent;
     
    512513    XCharStruct *xcs = charStruct(_fs, glyph);
    513514    if (xcs) {
     515        // XCharStruct::rbearing is defined as distance from left edge to rightmost pixel
     516        // XCharStruct::width is defined as the advance
    514517        gm = glyph_metrics_t(xcs->lbearing, -xcs->ascent, xcs->rbearing- xcs->lbearing, xcs->ascent + xcs->descent,
    515518                              xcs->width, 0);
     
    694697            const_cast<QFontEngineXLFD *>(this)->fsType = freetype->fsType();
    695698        } else {
    696             QFontEngine::Properties properties = QFontEngine::properties();
    697699            face_id.index = 0;
    698             face_id.filename = "-" + properties.postscriptName;
     700            face_id.filename = '-' + QFontEngine::properties().postscriptName;
    699701        }
    700702    }
  • trunk/src/gui/text/qfontengine_x11_p.h

    r2 r561  
    22**
    33** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
    4 ** Contact: Qt Software Information (qt-info@nokia.com)
     4** All rights reserved.
     5** Contact: Nokia Corporation (qt-info@nokia.com)
    56**
    67** This file is part of the QtGui module of the Qt Toolkit.
     
    2122** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    2223**
    23 ** In addition, as a special exception, Nokia gives you certain
    24 ** additional rights. These rights are described in the Nokia Qt LGPL
    25 ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
    26 ** package.
     24** In addition, as a special exception, Nokia gives you certain additional
     25** rights.  These rights are described in the Nokia Qt LGPL Exception
     26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
    2727**
    2828** GNU General Public License Usage
     
    3434** met: http://www.gnu.org/copyleft/gpl.html.
    3535**
    36 ** If you are unsure which license is appropriate for your use, please
    37 ** contact the sales department at qt-sales@nokia.com.
     36** If you have questions regarding the use of this file, please contact
     37** Nokia at qt-info@nokia.com.
    3838** $QT_END_LICENSE$
    3939**
  • trunk/src/gui/text/qfontengineglyphcache_p.h

    r2 r561  
    22**
    33** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
    4 ** Contact: Qt Software Information (qt-info@nokia.com)
     4** All rights reserved.
     5** Contact: Nokia Corporation (qt-info@nokia.com)
    56**
    67** This file is part of the QtGui module of the Qt Toolkit.
     
    2122** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    2223**
    23 ** In addition, as a special exception, Nokia gives you certain
    24 ** additional rights. These rights are described in the Nokia Qt LGPL
    25 ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
    26 ** package.
     24** In addition, as a special exception, Nokia gives you certain additional
     25** rights.  These rights are described in the Nokia Qt LGPL Exception
     26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
    2727**
    2828** GNU General Public License Usage
     
    3434** met: http://www.gnu.org/copyleft/gpl.html.
    3535**
    36 ** If you are unsure which license is appropriate for your use, please
    37 ** contact the sales department at qt-sales@nokia.com.
     36** If you have questions regarding the use of this file, please contact
     37** Nokia at qt-info@nokia.com.
    3838** $QT_END_LICENSE$
    3939**
     
    7373QT_BEGIN_NAMESPACE
    7474
    75 class Q_GUI_EXPORT QFontEngineGlyphCache
     75class QFontEngineGlyphCache
    7676{
    7777public:
    78     QFontEngineGlyphCache(const QTransform &matrix) : m_transform(matrix) { }
    79 
    8078    enum Type {
    8179        Raster_RGBMask,
     
    8482    };
    8583
    86     virtual ~QFontEngineGlyphCache();
     84    QFontEngineGlyphCache(const QTransform &matrix, Type type) : m_transform(matrix), m_type(type) { }
     85
     86    virtual ~QFontEngineGlyphCache() { }
     87
     88    Type cacheType() const { return m_type; }
    8789
    8890    QTransform m_transform;
     91    QFontEngineGlyphCache::Type m_type;
    8992};
    9093typedef QHash<void *, QList<QFontEngineGlyphCache *> > GlyphPointerHash;
  • trunk/src/gui/text/qfontinfo.h

    r2 r561  
    22**
    33** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
    4 ** Contact: Qt Software Information (qt-info@nokia.com)
     4** All rights reserved.
     5** Contact: Nokia Corporation (qt-info@nokia.com)
    56**
    67** This file is part of the QtGui module of the Qt Toolkit.
     
    2122** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    2223**
    23 ** In addition, as a special exception, Nokia gives you certain
    24 ** additional rights. These rights are described in the Nokia Qt LGPL
    25 ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
    26 ** package.
     24** In addition, as a special exception, Nokia gives you certain additional
     25** rights.  These rights are described in the Nokia Qt LGPL Exception
     26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
    2727**
    2828** GNU General Public License Usage
     
    3434** met: http://www.gnu.org/copyleft/gpl.html.
    3535**
    36 ** If you are unsure which license is appropriate for your use, please
    37 ** contact the sales department at qt-sales@nokia.com.
     36** If you have questions regarding the use of this file, please contact
     37** Nokia at qt-info@nokia.com.
    3838** $QT_END_LICENSE$
    3939**
     
    4444
    4545#include <QtGui/qfont.h>
     46#include <QtCore/qsharedpointer.h>
    4647
    4748QT_BEGIN_HEADER
     
    7879
    7980private:
    80     QFontPrivate *d;
     81    QExplicitlySharedDataPointer<QFontPrivate> d;
    8182};
    8283
  • trunk/src/gui/text/qfontmetrics.cpp

    r2 r561  
    22**
    33** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
    4 ** Contact: Qt Software Information (qt-info@nokia.com)
     4** All rights reserved.
     5** Contact: Nokia Corporation (qt-info@nokia.com)
    56**
    67** This file is part of the QtGui module of the Qt Toolkit.
     
    2122** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    2223**
    23 ** In addition, as a special exception, Nokia gives you certain
    24 ** additional rights. These rights are described in the Nokia Qt LGPL
    25 ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
    26 ** package.
     24** In addition, as a special exception, Nokia gives you certain additional
     25** rights.  These rights are described in the Nokia Qt LGPL Exception
     26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
    2727**
    2828** GNU General Public License Usage
     
    3434** met: http://www.gnu.org/copyleft/gpl.html.
    3535**
    36 ** If you are unsure which license is appropriate for your use, please
    37 ** contact the sales department at qt-sales@nokia.com.
     36** If you have questions regarding the use of this file, please contact
     37** Nokia at qt-info@nokia.com.
    3838** $QT_END_LICENSE$
    3939**
     
    7676    \brief The QFontMetrics class provides font metrics information.
    7777
    78     \ingroup multimedia
     78    \ingroup painting
    7979    \ingroup shared
    80     \ingroup text
    8180
    8281    QFontMetrics functions calculate the size of characters and
     
    165164*/
    166165QFontMetrics::QFontMetrics(const QFont &font)
    167     : d(font.d)
    168 {
    169     d->ref.ref();
     166    : d(font.d.data())
     167{
    170168}
    171169
     
    197195        d->screen = screen;
    198196    } else {
    199         d = font.d;
    200         d->ref.ref();
     197        d = font.d.data();
    201198    }
    202199
     
    207204*/
    208205QFontMetrics::QFontMetrics(const QFontMetrics &fm)
    209     : d(fm.d)
    210 { d->ref.ref(); }
     206    : d(fm.d.data())
     207{
     208}
    211209
    212210/*!
     
    216214QFontMetrics::~QFontMetrics()
    217215{
    218     if (!d->ref.deref())
    219         delete d;
    220216}
    221217
     
    225221QFontMetrics &QFontMetrics::operator=(const QFontMetrics &fm)
    226222{
    227     qAtomicAssign(d, fm.d);
     223    d = fm.d.data();
    228224    return *this;
    229225}
     
    529525int QFontMetrics::width(const QString &text, int len) const
    530526{
    531     if (len < 0)
     527    int pos = text.indexOf(QLatin1Char('\x9c'));
     528    if (pos != -1) {
     529        len = (len < 0) ? pos : qMin(pos, len);
     530    } else if (len < 0) {
    532531        len = text.length();
     532    }
    533533    if (len == 0)
    534534        return 0;
    535535
    536     QTextEngine layout(text, d);
     536    QTextEngine layout(text, d.data());
    537537    layout.ignoreBidi = true;
    538538    return qRound(layout.width(0, len));
     
    558558    characters or non-spacing marks in the middle of a string, as the
    559559    glyph shaping and positioning of marks that happens when
    560     processing strings cannot be taken into account. Use charWidth()
    561     instead if you aren't looking for the width of isolated
    562     characters.
    563 
    564     \sa boundingRect(), charWidth()
     560    processing strings cannot be taken into account. When implementing
     561    an interactive text control, use QTextLayout instead.
     562
     563    \sa boundingRect()
    565564*/
    566565int QFontMetrics::width(QChar ch) const
     
    611610        int to = qMin(text.length(), pos + 8);
    612611        QString cstr = QString::fromRawData(text.unicode() + from, to - from);
    613         QTextEngine layout(cstr, d);
     612        QTextEngine layout(cstr, d.data());
    614613        layout.ignoreBidi = true;
    615614        layout.itemize();
     
    660659        return QRect();
    661660
    662     QTextEngine layout(text, d);
     661    QTextEngine layout(text, d.data());
    663662    layout.ignoreBidi = true;
    664663    layout.itemize();
     
    671670    were to be drawn at the origin of the coordinate system.
    672671
    673     Note that the bounding rectangle may extend to the left of (0, 0),
    674     e.g. for italicized fonts, and that the text output may cover \e
     672    Note that the bounding rectangle may extend to the left of (0, 0)
     673    (e.g., for italicized fonts), and that the text output may cover \e
    675674    all pixels in the bounding rectangle. For a space character the rectangle
    676675    will usually be empty.
     
    725724    \o Qt::TextSingleLine ignores newline characters in the text.
    726725    \o Qt::TextExpandTabs expands tabs (see below)
    727     \o Qt::TextShowMnemonic interprets "&amp;x" as \underline{x}, i.e. underlined.
     726    \o Qt::TextShowMnemonic interprets "&x" as \underline{x}; i.e., underlined.
    728727    \o Qt::TextWordWrap breaks the text to fit the rectangle.
    729728    \endlist
     
    769768    QRectF rb;
    770769    QRectF rr(rect);
    771     qt_format_text(QFont(d), rr, flags | Qt::TextDontPrint, text, &rb, tabStops, tabArray,
     770    qt_format_text(QFont(d.data()), rr, flags | Qt::TextDontPrint, text, &rb, tabStops, tabArray,
    772771                   tabArrayLen, 0);
    773772
     
    782781    \o Qt::TextSingleLine ignores newline characters.
    783782    \o Qt::TextExpandTabs expands tabs (see below)
    784     \o Qt::TextShowMnemonic interprets "&amp;x" as \underline{x}, i.e. underlined.
     783    \o Qt::TextShowMnemonic interprets "&x" as \underline{x}; i.e., underlined.
    785784    \o Qt::TextWordBreak breaks the text to fit the rectangle.
    786785    \endlist
     
    800799QSize QFontMetrics::size(int flags, const QString &text, int tabStops, int *tabArray) const
    801800{
    802     return boundingRect(QRect(0,0,0,0), flags, text, tabStops, tabArray).size();
     801    return boundingRect(QRect(0,0,0,0), flags | Qt::TextLongestVariant, text, tabStops, tabArray).size();
    803802}
    804803
     
    830829        return QRect();
    831830
    832     QTextEngine layout(text, d);
     831    QTextEngine layout(text, d.data());
    833832    layout.ignoreBidi = true;
    834833    layout.itemize();
     
    859858    layouts. Note that this behavior is independent of the text
    860859    language.
    861 
    862860*/
    863861QString QFontMetrics::elidedText(const QString &text, Qt::TextElideMode mode, int width, int flags) const
    864862{
    865     QStackTextEngine engine(text, QFont(d));
     863    QString _text = text;
     864    if (!(flags & Qt::TextLongestVariant)) {
     865        int posA = 0;
     866        int posB = _text.indexOf(QLatin1Char('\x9c'));
     867        while (posB >= 0) {
     868            QString portion = _text.mid(posA, posB - posA);
     869            if (size(flags, portion).width() <= width)
     870                return portion;
     871            posA = posB + 1;
     872            posB = _text.indexOf(QLatin1Char('\x9c'), posA);
     873        }
     874        _text = _text.mid(posA);
     875    }
     876    QStackTextEngine engine(_text, QFont(d.data()));
    866877    return engine.elidedText(mode, width, flags);
    867878}
     
    929940    \brief The QFontMetricsF class provides font metrics information.
    930941
    931     \ingroup multimedia
     942    \ingroup painting
    932943    \ingroup shared
    933     \ingroup text
    934944
    935945    QFontMetricsF functions calculate the size of characters and
     
    977987*/
    978988QFontMetricsF::QFontMetricsF(const QFontMetrics &fontMetrics)
    979     : d(fontMetrics.d)
    980 {
    981     d->ref.ref();
     989    : d(fontMetrics.d.data())
     990{
    982991}
    983992
     
    989998QFontMetricsF &QFontMetricsF::operator=(const QFontMetrics &other)
    990999{
    991     qAtomicAssign(d, other.d);
     1000    d = other.d.data();
    9921001    return *this;
    9931002}
     
    10071016*/
    10081017QFontMetricsF::QFontMetricsF(const QFont &font)
    1009     : d(font.d)
    1010 {
    1011     d->ref.ref();
     1018    : d(font.d.data())
     1019{
    10121020}
    10131021
     
    10391047        d->screen = screen;
    10401048    } else {
    1041         d = font.d;
    1042         d->ref.ref();
     1049        d = font.d.data();
    10431050    }
    10441051
     
    10491056*/
    10501057QFontMetricsF::QFontMetricsF(const QFontMetricsF &fm)
    1051     : d(fm.d)
    1052 { d->ref.ref(); }
     1058    : d(fm.d.data())
     1059{
     1060}
    10531061
    10541062/*!
     
    10581066QFontMetricsF::~QFontMetricsF()
    10591067{
    1060     if (!d->ref.deref())
    1061         delete d;
    10621068}
    10631069
     
    10671073QFontMetricsF &QFontMetricsF::operator=(const QFontMetricsF &fm)
    10681074{
    1069     qAtomicAssign(d, fm.d);
     1075    d = fm.d.data();
    10701076    return *this;
    10711077}
     
    13621368qreal QFontMetricsF::width(const QString &text) const
    13631369{
    1364     QTextEngine layout(text, d);
     1370    int pos = text.indexOf(QLatin1Char('\x9c'));
     1371    int len = (pos != -1) ? pos : text.length();
     1372
     1373    QTextEngine layout(text, d.data());
    13651374    layout.ignoreBidi = true;
    13661375    layout.itemize();
    1367     return layout.width(0, text.length()).toReal();
     1376    return layout.width(0, len).toReal();
    13681377}
    13691378
     
    13871396    characters or non-spacing marks in the middle of a string, as the
    13881397    glyph shaping and positioning of marks that happens when
    1389     processing strings cannot be taken into account. Use charWidth()
    1390     instead if you aren't looking for the width of isolated
    1391     characters.
     1398    processing strings cannot be taken into account. When implementing
     1399    an interactive text control, use QTextLayout instead.
    13921400
    13931401    \sa boundingRect()
     
    14401448        return QRectF();
    14411449
    1442     QTextEngine layout(text, d);
     1450    QTextEngine layout(text, d.data());
    14431451    layout.ignoreBidi = true;
    14441452    layout.itemize();
     
    15011509    \o Qt::TextSingleLine ignores newline characters in the text.
    15021510    \o Qt::TextExpandTabs expands tabs (see below)
    1503     \o Qt::TextShowMnemonic interprets "&amp;x" as \underline{x}, i.e. underlined.
     1511    \o Qt::TextShowMnemonic interprets "&x" as \underline{x}; i.e., underlined.
    15041512    \o Qt::TextWordWrap breaks the text to fit the rectangle.
    15051513    \endlist
     
    15481556
    15491557    QRectF rb;
    1550     qt_format_text(QFont(d), rect, flags | Qt::TextDontPrint, text, &rb, tabStops, tabArray,
     1558    qt_format_text(QFont(d.data()), rect, flags | Qt::TextDontPrint, text, &rb, tabStops, tabArray,
    15511559                   tabArrayLen, 0);
    15521560    return rb;
     
    15601568    \o Qt::TextSingleLine ignores newline characters.
    15611569    \o Qt::TextExpandTabs expands tabs (see below)
    1562     \o Qt::TextShowMnemonic interprets "&amp;x" as \underline{x}, i.e. underlined.
     1570    \o Qt::TextShowMnemonic interprets "&x" as \underline{x}; i.e., underlined.
    15631571    \o Qt::TextWordBreak breaks the text to fit the rectangle.
    15641572    \endlist
     
    15831591QSizeF QFontMetricsF::size(int flags, const QString &text, int tabStops, int *tabArray) const
    15841592{
    1585     return boundingRect(QRectF(), flags, text, tabStops, tabArray).size();
     1593    return boundingRect(QRectF(), flags | Qt::TextLongestVariant, text, tabStops, tabArray).size();
    15861594}
    15871595
     
    16131621        return QRect();
    16141622
    1615     QTextEngine layout(text, d);
     1623    QTextEngine layout(text, d.data());
    16161624    layout.ignoreBidi = true;
    16171625    layout.itemize();
     
    16381646QString QFontMetricsF::elidedText(const QString &text, Qt::TextElideMode mode, qreal width, int flags) const
    16391647{
    1640     QStackTextEngine engine(text, QFont(d));
     1648    QString _text = text;
     1649    if (!(flags & Qt::TextLongestVariant)) {
     1650        int posA = 0;
     1651        int posB = _text.indexOf(QLatin1Char('\x9c'));
     1652        while (posB >= 0) {
     1653            QString portion = _text.mid(posA, posB - posA);
     1654            if (size(flags, portion).width() <= width)
     1655                return portion;
     1656            posA = posB + 1;
     1657            posB = _text.indexOf(QLatin1Char('\x9c'), posA);
     1658        }
     1659        _text = _text.mid(posA);
     1660    }
     1661    QStackTextEngine engine(_text, QFont(d.data()));
    16411662    return engine.elidedText(mode, QFixed::fromReal(width), flags);
    16421663}
  • trunk/src/gui/text/qfontmetrics.h

    r2 r561  
    22**
    33** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
    4 ** Contact: Qt Software Information (qt-info@nokia.com)
     4** All rights reserved.
     5** Contact: Nokia Corporation (qt-info@nokia.com)
    56**
    67** This file is part of the QtGui module of the Qt Toolkit.
     
    2122** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    2223**
    23 ** In addition, as a special exception, Nokia gives you certain
    24 ** additional rights. These rights are described in the Nokia Qt LGPL
    25 ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
    26 ** package.
     24** In addition, as a special exception, Nokia gives you certain additional
     25** rights.  These rights are described in the Nokia Qt LGPL Exception
     26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
    2727**
    2828** GNU General Public License Usage
     
    3434** met: http://www.gnu.org/copyleft/gpl.html.
    3535**
    36 ** If you are unsure which license is appropriate for your use, please
    37 ** contact the sales department at qt-sales@nokia.com.
     36** If you have questions regarding the use of this file, please contact
     37** Nokia at qt-info@nokia.com.
    3838** $QT_END_LICENSE$
    3939**
     
    4444
    4545#include <QtGui/qfont.h>
     46#include <QtCore/qsharedpointer.h>
    4647#ifndef QT_INCLUDE_COMPAT
    4748#include <QtCore/qrect.h>
     
    132133    friend class QStackTextEngine;
    133134
    134     QFontPrivate *d;
     135    QExplicitlySharedDataPointer<QFontPrivate> d;
    135136};
    136137
     
    188189
    189190private:
    190     QFontPrivate *d;
     191    QExplicitlySharedDataPointer<QFontPrivate> d;
    191192};
    192193
  • trunk/src/gui/text/qfontsubset.cpp

    r396 r561  
    22**
    33** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
    4 ** Contact: Qt Software Information (qt-info@nokia.com)
     4** All rights reserved.
     5** Contact: Nokia Corporation (qt-info@nokia.com)
    56**
    67** This file is part of the QtGui module of the Qt Toolkit.
     
    2122** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    2223**
    23 ** In addition, as a special exception, Nokia gives you certain
    24 ** additional rights. These rights are described in the Nokia Qt LGPL
    25 ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
    26 ** package.
     24** In addition, as a special exception, Nokia gives you certain additional
     25** rights.  These rights are described in the Nokia Qt LGPL Exception
     26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
    2727**
    2828** GNU General Public License Usage
     
    3434** met: http://www.gnu.org/copyleft/gpl.html.
    3535**
    36 ** If you are unsure which license is appropriate for your use, please
    37 ** contact the sales department at qt-sales@nokia.com.
     36** If you have questions regarding the use of this file, please contact
     37** Nokia at qt-info@nokia.com.
    3838** $QT_END_LICENSE$
    3939**
     
    334334    }
    335335    if (name[0]) {
    336         s << "/" << name;
     336        s << '/' << name;
    337337    } else
    338338#endif
     
    340340    if (fontEngine->type() == QFontEngine::XLFD) {
    341341        uint uc = static_cast<QFontEngineXLFD *>(fontEngine)->toUnicode(glyphIndex);
    342         s << "/" << glyphName(uc, false /* ### */);
     342        s << '/' << glyphName(uc, false /* ### */);
    343343    } else
    344344#endif
    345345    if (reverseMap[glyphIndex] && reverseMap[glyphIndex] < 0x10000) {
    346         s << "/" << glyphName(reverseMap[glyphIndex], false);
     346        s << '/' << glyphName(reverseMap[glyphIndex], false);
    347347    } else {
    348348        s << "/gl" << (int)glyphIndex;
     
    396396            // qDebug("    startLinear=%x endnonlinear=%x", startLinear,endnonlinear);
    397397            if (endnonlinear > start) {
    398                 s << start << "[";
     398                s << start << '[';
    399399                for (int i = start; i < endnonlinear; ++i)
    400400                    s << (widths[i]*scale).toInt();
     
    402402            }
    403403            if (startLinear)
    404                 s << startLinear << g - 1 << (widths[startLinear]*scale).toInt() << "\n";
     404                s << startLinear << g - 1 << (widths[startLinear]*scale).toInt() << '\n';
    405405        }
    406406        s << "]\n";
     
    489489        // qDebug("    startLinear=%x endnonlinear=%x", startLinear,endnonlinear);
    490490        if (endnonlinear > start) {
    491             s << "<" << QPdf::toHex((ushort)start, buf) << "> <";
     491            s << '<' << QPdf::toHex((ushort)start, buf) << "> <";
    492492            s << QPdf::toHex((ushort)(endnonlinear - 1), buf) << "> ";
    493493            if (endnonlinear == start + 1) {
    494                 s << "<" << QPdf::toHex((ushort)reverseMap[start], buf) << ">\n";
     494                s << '<' << QPdf::toHex((ushort)reverseMap[start], buf) << ">\n";
    495495            } else {
    496                 s << "[";
     496                s << '[';
    497497                for (int i = start; i < endnonlinear; ++i) {
    498                     s << "<" << QPdf::toHex((ushort)reverseMap[i], buf) << "> ";
     498                    s << '<' << QPdf::toHex((ushort)reverseMap[i], buf) << "> ";
    499499                }
    500500                s << "]\n";
     
    509509                if ((uc_end >> 8) != (uc_start >> 8))
    510510                    len = 256 - (uc_start & 0xff);
    511                 s << "<" << QPdf::toHex((ushort)startLinear, buf) << "> <";
     511                s << '<' << QPdf::toHex((ushort)startLinear, buf) << "> <";
    512512                s << QPdf::toHex((ushort)(startLinear + len - 1), buf) << "> ";
    513                 s << "<" << QPdf::toHex((ushort)reverseMap[startLinear], buf) << ">\n";
     513                s << '<' << QPdf::toHex((ushort)reverseMap[startLinear], buf) << ">\n";
    514514                checkRanges(ts, ranges, nranges);
    515515                startLinear += len;
     
    16561656    QByteArray id = QByteArray::number(object_id);
    16571657    QByteArray psname = properties.postscriptName;
    1658     psname.replace(" ", "");
     1658    psname.replace(' ', "");
    16591659
    16601660    standard_font = false;
     
    16821682    s << "/F" << id << "-Base\n";
    16831683    if (standard_font) {
    1684             s << "/" << psname << " findfont\n"
     1684            s << '/' << psname << " findfont\n"
    16851685                "0 dict copy dup /NumGlyphs 0 put dup /CMap 256 array put def\n";
    16861686    } else {
    16871687        s << "<<\n";
    16881688        if(!psname.isEmpty())
    1689             s << "/FontName /" << psname << "\n";
     1689            s << "/FontName /" << psname << '\n';
    16901690        s << "/FontInfo <</FsType " << (int)fontEngine->fsType << ">>\n"
    16911691            "/FontType 1\n"
     
    17231723    QByteArray id = QByteArray::number(object_id);
    17241724
    1725     s << "F" << id << "-Base [\n";
     1725    s << 'F' << id << "-Base [\n";
    17261726    for (int i = downloaded_glyphs; i < nGlyphs; ++i) {
    17271727        glyph_t g = glyph_indices.at(i);
  • trunk/src/gui/text/qfontsubset_p.h

    r2 r561  
    22**
    33** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
    4 ** Contact: Qt Software Information (qt-info@nokia.com)
     4** All rights reserved.
     5** Contact: Nokia Corporation (qt-info@nokia.com)
    56**
    67** This file is part of the QtGui module of the Qt Toolkit.
     
    2122** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    2223**
    23 ** In addition, as a special exception, Nokia gives you certain
    24 ** additional rights. These rights are described in the Nokia Qt LGPL
    25 ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
    26 ** package.
     24** In addition, as a special exception, Nokia gives you certain additional
     25** rights.  These rights are described in the Nokia Qt LGPL Exception
     26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
    2727**
    2828** GNU General Public License Usage
     
    3434** met: http://www.gnu.org/copyleft/gpl.html.
    3535**
    36 ** If you are unsure which license is appropriate for your use, please
    37 ** contact the sales department at qt-sales@nokia.com.
     36** If you have questions regarding the use of this file, please contact
     37** Nokia at qt-info@nokia.com.
    3838** $QT_END_LICENSE$
    3939**
  • trunk/src/gui/text/qfragmentmap.cpp

    r2 r561  
    22**
    33** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
    4 ** Contact: Qt Software Information (qt-info@nokia.com)
     4** All rights reserved.
     5** Contact: Nokia Corporation (qt-info@nokia.com)
    56**
    67** This file is part of the QtGui module of the Qt Toolkit.
     
    2122** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    2223**
    23 ** In addition, as a special exception, Nokia gives you certain
    24 ** additional rights. These rights are described in the Nokia Qt LGPL
    25 ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
    26 ** package.
     24** In addition, as a special exception, Nokia gives you certain additional
     25** rights.  These rights are described in the Nokia Qt LGPL Exception
     26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
    2727**
    2828** GNU General Public License Usage
     
    3434** met: http://www.gnu.org/copyleft/gpl.html.
    3535**
    36 ** If you are unsure which license is appropriate for your use, please
    37 ** contact the sales department at qt-sales@nokia.com.
     36** If you have questions regarding the use of this file, please contact
     37** Nokia at qt-info@nokia.com.
    3838** $QT_END_LICENSE$
    3939**
  • trunk/src/gui/text/qfragmentmap_p.h

    r2 r561  
    22**
    33** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
    4 ** Contact: Qt Software Information (qt-info@nokia.com)
     4** All rights reserved.
     5** Contact: Nokia Corporation (qt-info@nokia.com)
    56**
    67** This file is part of the QtGui module of the Qt Toolkit.
     
    2122** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    2223**
    23 ** In addition, as a special exception, Nokia gives you certain
    24 ** additional rights. These rights are described in the Nokia Qt LGPL
    25 ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
    26 ** package.
     24** In addition, as a special exception, Nokia gives you certain additional
     25** rights.  These rights are described in the Nokia Qt LGPL Exception
     26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
    2727**
    2828** GNU General Public License Usage
     
    3434** met: http://www.gnu.org/copyleft/gpl.html.
    3535**
    36 ** If you are unsure which license is appropriate for your use, please
    37 ** contact the sales department at qt-sales@nokia.com.
     36** If you have questions regarding the use of this file, please contact
     37** Nokia at qt-info@nokia.com.
    3838** $QT_END_LICENSE$
    3939**
     
    215215template <class Fragment>
    216216QFragmentMapData<Fragment>::QFragmentMapData()
     217    : fragments(0)
    217218{
    218219    init();
     
    222223void QFragmentMapData<Fragment>::init()
    223224{
    224     fragments = (Fragment *)malloc(64*fragmentSize);
     225    // the following code will realloc an existing fragment or create a new one.
     226    // it will also ignore errors when shrinking an existing fragment.
     227    Fragment *newFragments = (Fragment *)realloc(fragments, 64*fragmentSize);
     228    if (newFragments) {
     229        fragments = newFragments;
     230        head->allocated = 64;
     231    }
     232    Q_CHECK_PTR(fragments);
     233
    225234    head->tag = (((quint32)'p') << 24) | (((quint32)'m') << 16) | (((quint32)'a') << 8) | 'p'; //TAG('p', 'm', 'a', 'p');
    226235    head->root = 0;
    227236    head->freelist = 1;
    228237    head->node_count = 0;
    229     head->allocated = 64;
    230238    // mark all items to the right as unused
    231239    F(head->freelist).right = 0;
     
    235243QFragmentMapData<Fragment>::~QFragmentMapData()
    236244{
    237     free(head);
     245    free(fragments);
    238246}
    239247
     
    248256        uint needed = qAllocMore((freePos+1)*fragmentSize, 0);
    249257        Q_ASSERT(needed/fragmentSize > head->allocated);
    250         fragments = (Fragment *)realloc(fragments, needed);
     258        Fragment *newFragments = (Fragment *)realloc(fragments, needed);
     259        Q_CHECK_PTR(newFragments);
     260        fragments = newFragments;
    251261        head->allocated = needed/fragmentSize;
    252262        F(freePos).right = 0;
     
    788798    ~QFragmentMap()
    789799    {
     800        if (!data.fragments)
     801            return; // in case of out-of-memory, we won't have fragments
    790802        for (Iterator it = begin(); !it.atEnd(); ++it)
    791803            it.value()->free();
     
    795807        for (Iterator it = begin(); !it.atEnd(); ++it)
    796808            it.value()->free();
    797         ::free(data.head);
    798809        data.init();
    799810    }
  • trunk/src/gui/text/qpfutil.cpp

    r2 r561  
    22**
    33** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
    4 ** Contact: Qt Software Information (qt-info@nokia.com)
     4** All rights reserved.
     5** Contact: Nokia Corporation (qt-info@nokia.com)
    56**
    67** This file is part of the QtGui module of the Qt Toolkit.
     
    2122** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    2223**
    23 ** In addition, as a special exception, Nokia gives you certain
    24 ** additional rights. These rights are described in the Nokia Qt LGPL
    25 ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
    26 ** package.
     24** In addition, as a special exception, Nokia gives you certain additional
     25** rights.  These rights are described in the Nokia Qt LGPL Exception
     26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
    2727**
    2828** GNU General Public License Usage
     
    3434** met: http://www.gnu.org/copyleft/gpl.html.
    3535**
    36 ** If you are unsure which license is appropriate for your use, please
    37 ** contact the sales department at qt-sales@nokia.com.
     36** If you have questions regarding the use of this file, please contact
     37** Nokia at qt-info@nokia.com.
    3838** $QT_END_LICENSE$
    3939**
  • trunk/src/gui/text/qsyntaxhighlighter.cpp

    r2 r561  
    22**
    33** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
    4 ** Contact: Qt Software Information (qt-info@nokia.com)
     4** All rights reserved.
     5** Contact: Nokia Corporation (qt-info@nokia.com)
    56**
    67** This file is part of the QtGui module of the Qt Toolkit.
     
    2122** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    2223**
    23 ** In addition, as a special exception, Nokia gives you certain
    24 ** additional rights. These rights are described in the Nokia Qt LGPL
    25 ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
    26 ** package.
     24** In addition, as a special exception, Nokia gives you certain additional
     25** rights.  These rights are described in the Nokia Qt LGPL Exception
     26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
    2727**
    2828** GNU General Public License Usage
     
    3434** met: http://www.gnu.org/copyleft/gpl.html.
    3535**
    36 ** If you are unsure which license is appropriate for your use, please
    37 ** contact the sales department at qt-sales@nokia.com.
     36** If you have questions regarding the use of this file, please contact
     37** Nokia at qt-info@nokia.com.
    3838** $QT_END_LICENSE$
    3939**
     
    6666    void _q_reformatBlocks(int from, int charsRemoved, int charsAdded);
    6767    void reformatBlock(QTextBlock block);
     68   
     69    inline void rehighlight(QTextCursor &cursor, QTextCursor::MoveOperation operation) {
     70        QObject::disconnect(doc, SIGNAL(contentsChange(int,int,int)),
     71                            q_func(), SLOT(_q_reformatBlocks(int,int,int)));
     72        cursor.beginEditBlock();
     73        int from = cursor.position();
     74        cursor.movePosition(operation);
     75        _q_reformatBlocks(from, 0, cursor.position() - from);
     76        cursor.endEditBlock();
     77        QObject::connect(doc, SIGNAL(contentsChange(int,int,int)),
     78                         q_func(), SLOT(_q_reformatBlocks(int,int,int)));
     79    }
    6880
    6981    inline void _q_delayedRehighlight() {
     
    159171
    160172    int endPosition;
    161     QTextBlock lastBlock = doc->findBlock(from + charsAdded);
     173    QTextBlock lastBlock = doc->findBlock(from + charsAdded + (charsRemoved > 0 ? 1 : 0));
    162174    if (lastBlock.isValid())
    163175        endPosition = lastBlock.position() + lastBlock.length();
     
    208220    \since 4.1
    209221
    210     \ingroup text
     222    \ingroup richtext-processing
    211223
    212224    The QSyntaxHighlighter class is a base class for implementing
     
    356368    \since 4.2
    357369
    358     Redoes the highlighting of the whole document.
     370    Reapplies the highlighting to the whole document.
     371
     372    \sa rehighlightBlock()
    359373*/
    360374void QSyntaxHighlighter::rehighlight()
     
    364378        return;
    365379
    366     disconnect(d->doc, SIGNAL(contentsChange(int,int,int)),
    367                this, SLOT(_q_reformatBlocks(int,int,int)));
    368380    QTextCursor cursor(d->doc);
    369     cursor.beginEditBlock();
    370     cursor.movePosition(QTextCursor::End);
    371     d->_q_reformatBlocks(0, 0, cursor.position());
    372     cursor.endEditBlock();
    373     connect(d->doc, SIGNAL(contentsChange(int,int,int)),
    374             this, SLOT(_q_reformatBlocks(int,int,int)));
     381    d->rehighlight(cursor, QTextCursor::End);
     382}
     383
     384/*!
     385    \since 4.6
     386
     387    Reapplies the highlighting to the given QTextBlock \a block.
     388   
     389    \sa rehighlight()
     390*/
     391void QSyntaxHighlighter::rehighlightBlock(const QTextBlock &block)
     392{
     393    Q_D(QSyntaxHighlighter);
     394    if (!d->doc)
     395        return;
     396
     397    QTextCursor cursor(block);
     398    d->rehighlight(cursor, QTextCursor::EndOfBlock);
    375399}
    376400
  • trunk/src/gui/text/qsyntaxhighlighter.h

    r2 r561  
    22**
    33** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
    4 ** Contact: Qt Software Information (qt-info@nokia.com)
     4** All rights reserved.
     5** Contact: Nokia Corporation (qt-info@nokia.com)
    56**
    67** This file is part of the QtGui module of the Qt Toolkit.
     
    2122** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    2223**
    23 ** In addition, as a special exception, Nokia gives you certain
    24 ** additional rights. These rights are described in the Nokia Qt LGPL
    25 ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
    26 ** package.
     24** In addition, as a special exception, Nokia gives you certain additional
     25** rights.  These rights are described in the Nokia Qt LGPL Exception
     26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
    2727**
    2828** GNU General Public License Usage
     
    3434** met: http://www.gnu.org/copyleft/gpl.html.
    3535**
    36 ** If you are unsure which license is appropriate for your use, please
    37 ** contact the sales department at qt-sales@nokia.com.
     36** If you have questions regarding the use of this file, please contact
     37** Nokia at qt-info@nokia.com.
    3838** $QT_END_LICENSE$
    3939**
     
    7979public Q_SLOTS:
    8080    void rehighlight();
     81    void rehighlightBlock(const QTextBlock &block);
    8182
    8283protected:
  • trunk/src/gui/text/qtextcontrol.cpp

    r2 r561  
    22**
    33** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
    4 ** Contact: Qt Software Information (qt-info@nokia.com)
     4** All rights reserved.
     5** Contact: Nokia Corporation (qt-info@nokia.com)
    56**
    67** This file is part of the QtGui module of the Qt Toolkit.
     
    2122** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    2223**
    23 ** In addition, as a special exception, Nokia gives you certain
    24 ** additional rights. These rights are described in the Nokia Qt LGPL
    25 ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
    26 ** package.
     24** In addition, as a special exception, Nokia gives you certain additional
     25** rights.  These rights are described in the Nokia Qt LGPL Exception
     26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
    2727**
    2828** GNU General Public License Usage
     
    3434** met: http://www.gnu.org/copyleft/gpl.html.
    3535**
    36 ** If you are unsure which license is appropriate for your use, please
    37 ** contact the sales department at qt-sales@nokia.com.
     36** If you have questions regarding the use of this file, please contact
     37** Nokia at qt-info@nokia.com.
    3838** $QT_END_LICENSE$
    3939**
     
    5656#include <qtimer.h>
    5757#include "private/qtextdocumentlayout_p.h"
     58#include "private/qabstracttextdocumentlayout_p.h"
    5859#include "private/qtextedit_p.h"
    5960#include "qtextdocument.h"
     
    8384#include "private/qshortcutmap_p.h"
    8485#include <qkeysequence.h>
    85 #define ACCEL_KEY(k) (!qApp->d_func()->shortcutMap.hasShortcutForKeySequence(k) ? QLatin1String("\t") + QString(QKeySequence(k)) : QString())
     86#define ACCEL_KEY(k) (!qApp->d_func()->shortcutMap.hasShortcutForKeySequence(k) ? QLatin1Char('\t') + QString(QKeySequence(k)) : QString())
    8687#else
    8788#define ACCEL_KEY(k) QString()
     
    127128      isEnabled(true),
    128129      hadSelectionOnMousePress(false),
     130      ignoreUnusedNavigationEvents(false),
    129131      openExternalLinks(false)
    130132{}
     
    265267    q->ensureCursorVisible();
    266268
     269    bool ignoreNavigationEvents = ignoreUnusedNavigationEvents;
     270    bool isNavigationEvent = e->key() == Qt::Key_Up || e->key() == Qt::Key_Down;
     271
     272#ifdef QT_KEYPAD_NAVIGATION
     273    ignoreNavigationEvents = ignoreNavigationEvents || QApplication::keypadNavigationEnabled();
     274    isNavigationEvent = isNavigationEvent ||
     275                        (QApplication::navigationMode() == Qt::NavigationModeKeypadDirectional
     276                         && (e->key() == Qt::Key_Left || e->key() == Qt::Key_Right));
     277#else
     278    isNavigationEvent = isNavigationEvent || e->key() == Qt::Key_Left || e->key() == Qt::Key_Right;
     279#endif
     280
    267281    if (moved) {
    268282        if (cursor.position() != oldCursorPos)
    269283            emit q->cursorPositionChanged();
    270284        emit q->microFocusChanged();
    271     }
    272 #ifdef QT_KEYPAD_NAVIGATION
    273     else if (QApplication::keypadNavigationEnabled()
    274         && (e->key() == Qt::Key_Up || e->key() == Qt::Key_Down)) {
     285    } else if (ignoreNavigationEvents && isNavigationEvent) {
    275286        return false;
    276287    }
    277 #endif
    278288
    279289    selectionChanged(/*forceEmitSelectionChanged =*/(mode == QTextCursor::KeepAnchor));
     
    395405    setContent(format, text, document);
    396406
    397     QWidget *parentWidget = qobject_cast<QWidget*>(q->parent());
     407    QWidget *parentWidget = qobject_cast<QWidget*>(parent);
    398408    if (parentWidget) {
    399409        QTextOption opt = doc->defaultTextOption();
     
    504514
    505515    Qt::DropActions actions = Qt::CopyAction;
    506     if (interactionFlags & Qt::TextEditable)
     516    Qt::DropAction action;
     517    if (interactionFlags & Qt::TextEditable) {
    507518        actions |= Qt::MoveAction;
    508     Qt::DropAction action = drag->exec(actions, Qt::MoveAction);
     519        action = drag->exec(actions, Qt::MoveAction);
     520    } else {
     521        action = drag->exec(actions, Qt::CopyAction);
     522    }
    509523
    510524    if (action == Qt::MoveAction && drag->target() != contextWidget)
     
    906920        case QEvent::MouseButtonPress: {
    907921            QMouseEvent *ev = static_cast<QMouseEvent *>(e);
    908             d->mousePressEvent(ev->button(), matrix.map(ev->pos()), ev->modifiers(),
     922            d->mousePressEvent(ev, ev->button(), matrix.map(ev->pos()), ev->modifiers(),
    909923                               ev->buttons(), ev->globalPos());
    910924            break; }
     
    974988        case QEvent::GraphicsSceneMousePress: {
    975989            QGraphicsSceneMouseEvent *ev = static_cast<QGraphicsSceneMouseEvent *>(e);
    976             d->mousePressEvent(ev->button(), matrix.map(ev->pos()), ev->modifiers(), ev->buttons(),
     990            d->mousePressEvent(ev, ev->button(), matrix.map(ev->pos()), ev->modifiers(), ev->buttons(),
    977991                               ev->screenPos());
    978992            break; }
     
    12221236    }
    12231237    else if (e == QKeySequence::DeleteEndOfWord) {
    1224         cursor.movePosition(QTextCursor::NextWord, QTextCursor::KeepAnchor);
     1238        if (!cursor.hasSelection())
     1239            cursor.movePosition(QTextCursor::NextWord, QTextCursor::KeepAnchor);
    12251240        cursor.removeSelectedText();
    12261241    }
    12271242    else if (e == QKeySequence::DeleteStartOfWord) {
    1228         cursor.movePosition(QTextCursor::PreviousWord, QTextCursor::KeepAnchor);
     1243        if (!cursor.hasSelection())
     1244            cursor.movePosition(QTextCursor::PreviousWord, QTextCursor::KeepAnchor);
    12291245        cursor.removeSelectedText();
    12301246    }
     
    12891305{
    12901306    Q_Q(QTextControl);
    1291     emit q->updateRequest(q->blockBoundingRect(block));
     1307    QRectF br = q->blockBoundingRect(block);
     1308    br.setRight(qreal(INT_MAX)); // the block might have shrunk
     1309    emit q->updateRequest(br);
    12921310}
    12931311
     
    14581476}
    14591477
    1460 void QTextControlPrivate::mousePressEvent(Qt::MouseButton button, const QPointF &pos, Qt::KeyboardModifiers modifiers,
     1478void QTextControlPrivate::mousePressEvent(QEvent *e, Qt::MouseButton button, const QPointF &pos, Qt::KeyboardModifiers modifiers,
    14611479                                          Qt::MouseButtons buttons, const QPoint &globalPos)
    14621480{
     
    14721490        }
    14731491    }
    1474     if (!(button & Qt::LeftButton))
    1475         return;
    1476 
    1477     if (!((interactionFlags & Qt::TextSelectableByMouse) || (interactionFlags & Qt::TextEditable)))
    1478         return;
     1492    if (!(button & Qt::LeftButton) ||
     1493        !((interactionFlags & Qt::TextSelectableByMouse) || (interactionFlags & Qt::TextEditable))) {
     1494            e->ignore();
     1495            return;
     1496    }
    14791497
    14801498    cursorIsFocusIndicator = false;
     
    15001518    } else {
    15011519        int cursorPos = q->hitTest(pos, Qt::FuzzyHit);
    1502         if (cursorPos == -1)
     1520        if (cursorPos == -1) {
     1521            e->ignore();
    15031522            return;
     1523        }
    15041524
    15051525#if !defined(QT_NO_IM)
     
    15121532                ctx->mouseHandler(cursorPos - cursor.position(), &ev);
    15131533            }
    1514             if (!layout->preeditAreaText().isEmpty())
     1534            if (!layout->preeditAreaText().isEmpty()) {
     1535                e->ignore();
    15151536                return;
     1537            }
    15161538        }
    15171539#endif
     
    16121634            emit q->cursorPositionChanged();
    16131635        _q_updateCurrentCharFormatAndSelection();
     1636#ifndef QT_NO_IM
     1637        if (QInputContext *ic = inputContext()) {
     1638            ic->update();
     1639        }
     1640#endif //QT_NO_IM
    16141641    } else {
    16151642        //emit q->visibilityRequest(QRectF(mousePos, QSizeF(1, 1)));
     
    17131740
    17141741    trippleClickPoint = pos;
    1715     trippleClickTimer.start(qApp->doubleClickInterval(), q);
     1742    trippleClickTimer.start(QApplication::doubleClickInterval(), q);
    17161743    if (doEmit) {
    17171744        selectionChanged();
     
    18141841void QTextControlPrivate::inputMethodEvent(QInputMethodEvent *e)
    18151842{
     1843    Q_Q(QTextControl);
    18161844    if (!(interactionFlags & Qt::TextEditable) || cursor.isNull()) {
    18171845        e->ignore();
    18181846        return;
    18191847    }
     1848    bool isGettingInput = !e->commitString().isEmpty()
     1849            || e->preeditString() != cursor.block().layout()->preeditAreaText()
     1850            || e->replacementLength() > 0;
     1851
    18201852    cursor.beginEditBlock();
    1821 
    1822     cursor.removeSelectedText();
     1853    if (isGettingInput) {
     1854        cursor.removeSelectedText();
     1855    }
    18231856
    18241857    // insert commit string
     
    18301863    }
    18311864
     1865    for (int i = 0; i < e->attributes().size(); ++i) {
     1866        const QInputMethodEvent::Attribute &a = e->attributes().at(i);
     1867        if (a.type == QInputMethodEvent::Selection) {
     1868            QTextCursor oldCursor = cursor;
     1869            int blockStart = a.start + cursor.block().position();
     1870            cursor.setPosition(blockStart, QTextCursor::MoveAnchor);
     1871            cursor.setPosition(blockStart + a.length, QTextCursor::KeepAnchor);
     1872            q->ensureCursorVisible();
     1873            repaintOldAndNewSelection(oldCursor);
     1874        }
     1875    }
     1876
    18321877    QTextBlock block = cursor.block();
    18331878    QTextLayout *layout = block.layout();
    1834     layout->setPreeditArea(cursor.position() - block.position(), e->preeditString());
     1879    if (isGettingInput)
     1880        layout->setPreeditArea(cursor.position() - block.position(), e->preeditString());
    18351881    QList<QTextLayout::FormatRange> overrides;
    18361882    preeditCursor = e->preeditString().length();
     
    18661912        return QVariant(d->cursor.charFormat().font());
    18671913    case Qt::ImCursorPosition:
    1868         return QVariant(d->cursor.selectionEnd() - block.position());
     1914        return QVariant(d->cursor.position() - block.position());
    18691915    case Qt::ImSurroundingText:
    18701916        return QVariant(block.text());
    18711917    case Qt::ImCurrentSelection:
    18721918        return QVariant(d->cursor.selectedText());
     1919    case Qt::ImMaximumTextLength:
     1920        return QVariant(); // No limit.
     1921    case Qt::ImAnchorPosition:
     1922        return QVariant(qBound(0, d->cursor.anchor() - block.position(), block.length()));
    18731923    default:
    18741924        return QVariant();
     
    18891939    if (e->gotFocus()) {
    18901940#ifdef QT_KEYPAD_NAVIGATION
    1891         if (!QApplication::keypadNavigationEnabled() || (hasEditFocus && e->reason() == Qt::PopupFocusReason)) {
     1941        if (!QApplication::keypadNavigationEnabled() || (hasEditFocus && (e->reason() == Qt::PopupFocusReason
     1942#ifdef Q_OS_SYMBIAN
     1943            || e->reason() == Qt::ActiveWindowFocusReason
     1944#endif
     1945            ))) {
    18921946#endif
    18931947        cursorOn = (interactionFlags & Qt::TextSelectableByKeyboard);
     
    22212275}
    22222276
     2277bool QTextControl::ignoreUnusedNavigationEvents() const
     2278{
     2279    Q_D(const QTextControl);
     2280    return d->ignoreUnusedNavigationEvents;
     2281}
     2282
     2283void QTextControl::setIgnoreUnusedNavigationEvents(bool ignore)
     2284{
     2285    Q_D(QTextControl);
     2286    d->ignoreUnusedNavigationEvents = ignore;
     2287}
     2288
    22232289void QTextControl::moveCursor(QTextCursor::MoveOperation op, QTextCursor::MoveMode mode)
    22242290{
     
    22632329#ifndef QT_NO_PRINTER
    22642330    Q_D(const QTextControl);
    2265     if (printer && !printer->isValid())
     2331    if (!printer || !printer->isValid())
    22662332        return;
    22672333    QTextDocument *tempDoc = 0;
     
    22772343        QTextCursor(tempDoc).insertFragment(d->cursor.selection());
    22782344        doc = tempDoc;
     2345
     2346        // copy the custom object handlers
     2347        doc->documentLayout()->d_func()->handlers = d->doc->documentLayout()->d_func()->handlers;
    22792348    }
    22802349    doc->print(printer);
  • trunk/src/gui/text/qtextcontrol_p.h

    r2 r561  
    22**
    33** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
    4 ** Contact: Qt Software Information (qt-info@nokia.com)
     4** All rights reserved.
     5** Contact: Nokia Corporation (qt-info@nokia.com)
    56**
    67** This file is part of the QtGui module of the Qt Toolkit.
     
    2122** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    2223**
    23 ** In addition, as a special exception, Nokia gives you certain
    24 ** additional rights. These rights are described in the Nokia Qt LGPL
    25 ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
    26 ** package.
     24** In addition, as a special exception, Nokia gives you certain additional
     25** rights.  These rights are described in the Nokia Qt LGPL Exception
     26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
    2727**
    2828** GNU General Public License Usage
     
    3434** met: http://www.gnu.org/copyleft/gpl.html.
    3535**
    36 ** If you are unsure which license is appropriate for your use, please
    37 ** contact the sales department at qt-sales@nokia.com.
     36** If you have questions regarding the use of this file, please contact
     37** Nokia at qt-info@nokia.com.
    3838** $QT_END_LICENSE$
    3939**
     
    9696    Q_PROPERTY(Qt::TextInteractionFlags textInteractionFlags READ textInteractionFlags WRITE setTextInteractionFlags)
    9797    Q_PROPERTY(bool openExternalLinks READ openExternalLinks WRITE setOpenExternalLinks)
     98    Q_PROPERTY(bool ignoreUnusedNavigationEvents READ ignoreUnusedNavigationEvents WRITE setIgnoreUnusedNavigationEvents)
    9899public:
    99100    explicit QTextControl(QObject *parent = 0);
     
    163164    void setOpenExternalLinks(bool open);
    164165    bool openExternalLinks() const;
     166
     167    void setIgnoreUnusedNavigationEvents(bool ignore);
     168    bool ignoreUnusedNavigationEvents() const;
    165169
    166170    void moveCursor(QTextCursor::MoveOperation op, QTextCursor::MoveMode mode = QTextCursor::MoveAnchor);
  • trunk/src/gui/text/qtextcontrol_p_p.h

    r2 r561  
    22**
    33** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
    4 ** Contact: Qt Software Information (qt-info@nokia.com)
     4** All rights reserved.
     5** Contact: Nokia Corporation (qt-info@nokia.com)
    56**
    67** This file is part of the QtGui module of the Qt Toolkit.
     
    2122** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    2223**
    23 ** In addition, as a special exception, Nokia gives you certain
    24 ** additional rights. These rights are described in the Nokia Qt LGPL
    25 ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
    26 ** package.
     24** In addition, as a special exception, Nokia gives you certain additional
     25** rights.  These rights are described in the Nokia Qt LGPL Exception
     26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
    2727**
    2828** GNU General Public License Usage
     
    3434** met: http://www.gnu.org/copyleft/gpl.html.
    3535**
    36 ** If you are unsure which license is appropriate for your use, please
    37 ** contact the sales department at qt-sales@nokia.com.
     36** If you have questions regarding the use of this file, please contact
     37** Nokia at qt-info@nokia.com.
    3838** $QT_END_LICENSE$
    3939**
     
    132132
    133133    void keyPressEvent(QKeyEvent *e);
    134     void mousePressEvent(Qt::MouseButton button, const QPointF &pos,
     134    void mousePressEvent(QEvent *e, Qt::MouseButton button, const QPointF &pos,
    135135                         Qt::KeyboardModifiers modifiers,
    136136                         Qt::MouseButtons buttons,
    137                          const QPoint &globalPos = QPoint());
     137                         const QPoint &globalPos);
    138138    void mouseMoveEvent(Qt::MouseButtons buttons, const QPointF &pos);
    139139    void mouseReleaseEvent(Qt::MouseButton button, const QPointF &pos);
     
    207207    bool hadSelectionOnMousePress;
    208208
     209    bool ignoreUnusedNavigationEvents;
    209210    bool openExternalLinks;
    210211
  • trunk/src/gui/text/qtextcursor.cpp

    r2 r561  
    22**
    33** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
    4 ** Contact: Qt Software Information (qt-info@nokia.com)
     4** All rights reserved.
     5** Contact: Nokia Corporation (qt-info@nokia.com)
    56**
    67** This file is part of the QtGui module of the Qt Toolkit.
     
    2122** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    2223**
    23 ** In addition, as a special exception, Nokia gives you certain
    24 ** additional rights. These rights are described in the Nokia Qt LGPL
    25 ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
    26 ** package.
     24** In addition, as a special exception, Nokia gives you certain additional
     25** rights.  These rights are described in the Nokia Qt LGPL Exception
     26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
    2727**
    2828** GNU General Public License Usage
     
    3434** met: http://www.gnu.org/copyleft/gpl.html.
    3535**
    36 ** If you are unsure which license is appropriate for your use, please
    37 ** contact the sales department at qt-sales@nokia.com.
     36** If you have questions regarding the use of this file, please contact
     37** Nokia at qt-info@nokia.com.
    3838** $QT_END_LICENSE$
    3939**
     
    9393    QTextCursorPrivate::AdjustResult result = QTextCursorPrivate::CursorMoved;
    9494    // not(!) <= , so that inserting text adjusts the cursor correctly
    95     if (position < positionOfChange ||
    96         (position == positionOfChange && op == QTextUndoCommand::KeepCursor)) {
     95    if (position < positionOfChange
     96        || (position == positionOfChange
     97            && (op == QTextUndoCommand::KeepCursor
     98                || anchor < position)
     99            )
     100         ) {
    97101        result = CursorUnchanged;
    98102    } else {
     
    126130void QTextCursorPrivate::setX()
    127131{
    128     if (priv && priv->isInEditBlock()) {
     132    if (priv->isInEditBlock()) {
    129133        x = -1; // mark dirty
    130134        return;
     
    146150    if (anchor == position)
    147151        return;
    148     priv->beginEditBlock();
    149152    currentCharFormat = -1;
    150153    int pos1 = position;
     
    160163    QTextTable *table = complexSelectionTable();
    161164    if (table) {
     165        priv->beginEditBlock();
    162166        int startRow, startCol, numRows, numCols;
    163167        selectedTableCells(&startRow, &numRows, &startCol, &numCols);
    164168        clearCells(table, startRow, startCol, numRows, numCols, op);
     169        adjusted_anchor = anchor = position;
     170        priv->endEditBlock();
    165171    } else {
    166172        priv->remove(pos1, pos2-pos1, op);
    167     }
    168 
    169     adjusted_anchor = anchor = position;
    170     priv->endEditBlock();
     173        adjusted_anchor = anchor = position;
     174        priv->finishEdit();
     175    }
     176
    171177}
    172178
     
    854860    \brief The QTextCursor class offers an API to access and modify QTextDocuments.
    855861
    856     \ingroup text
     862    \ingroup richtext-processing
    857863    \ingroup shared
    858     \mainclass
     864
    859865
    860866    Text cursors are objects that are used to access and modify the contents
     
    10751081
    10761082/*!
    1077     Makes a copy of \a cursor and assigns it to this QTextCursor.
     1083    Makes a copy of \a cursor and assigns it to this QTextCursor. Note
     1084    that QTextCursor is an \l{Implicitly Shared Classes}{implicitly
     1085    shared} class.
     1086
    10781087 */
    10791088QTextCursor &QTextCursor::operator=(const QTextCursor &cursor)
     
    12891298    format.clearProperty(QTextFormat::ObjectIndex);
    12901299
    1291     d->priv->beginEditBlock();
    1292 
    1293     d->remove();
     1300    bool hasEditBlock = false;
     1301
     1302    if (d->anchor != d->position) {
     1303        hasEditBlock = true;
     1304        d->priv->beginEditBlock();
     1305        d->remove();
     1306    }
     1307
    12941308    if (!text.isEmpty()) {
    12951309        QTextFormatCollection *formats = d->priv->formatCollection();
     
    13191333            if (ch == QLatin1Char('\n')
    13201334                || ch == QChar::ParagraphSeparator
     1335                || ch == QTextBeginningOfFrame
     1336                || ch == QTextEndOfFrame
    13211337                || ch == QLatin1Char('\r')) {
     1338
     1339                if (!hasEditBlock) {
     1340                    hasEditBlock = true;
     1341                    d->priv->beginEditBlock();
     1342                }
    13221343
    13231344                if (blockEnd > blockStart)
     
    13311352            d->priv->insert(d->position, textStart + blockStart, textEnd - textStart - blockStart, formatIdx);
    13321353    }
    1333     d->priv->endEditBlock();
     1354    if (hasEditBlock)
     1355        d->priv->endEditBlock();
    13341356    d->setX();
    13351357}
     
    13461368        return;
    13471369
    1348     if (d->position == d->anchor) {
    1349         if (!d->canDelete(d->position))
    1350             return;
    1351         d->adjusted_anchor = d->anchor =
    1352                              d->priv->nextCursorPosition(d->anchor, QTextLayout::SkipCharacters);
    1353     }
     1370    if (d->position != d->anchor) {
     1371        removeSelectedText();
     1372        return;
     1373    }
     1374
     1375    if (!d->canDelete(d->position))
     1376        return;
     1377    d->adjusted_anchor = d->anchor =
     1378                         d->priv->nextCursorPosition(d->anchor, QTextLayout::SkipCharacters);
    13541379    d->remove();
    13551380    d->setX();
     
    13661391    if (!d || !d->priv)
    13671392        return;
    1368 
    1369     if (d->position == d->anchor) {
    1370         if (d->anchor < 1 || !d->canDelete(d->anchor-1))
    1371             return;
    1372         d->anchor--;
    1373 
    1374         QTextDocumentPrivate::FragmentIterator fragIt = d->priv->find(d->anchor);
    1375         const QTextFragmentData * const frag = fragIt.value();
    1376         int fpos = fragIt.position();
    1377         QChar uc = d->priv->buffer().at(d->anchor - fpos + frag->stringPosition);
    1378         if (d->anchor > fpos && uc.unicode() >= 0xdc00 && uc.unicode() < 0xe000) {
    1379             // second half of a surrogate, check if we have the first half as well,
    1380             // if yes delete both at once
    1381             uc = d->priv->buffer().at(d->anchor - 1 - fpos + frag->stringPosition);
    1382             if (uc.unicode() >= 0xd800 && uc.unicode() < 0xdc00)
    1383                 --d->anchor;
    1384         }
    1385 
    1386         d->adjusted_anchor = d->anchor;
    1387     }
    1388 
     1393   
     1394    if (d->position != d->anchor) {
     1395        removeSelectedText();
     1396        return;
     1397    }
     1398   
     1399    if (d->anchor < 1 || !d->canDelete(d->anchor-1))
     1400        return;
     1401    d->anchor--;
     1402   
     1403    QTextDocumentPrivate::FragmentIterator fragIt = d->priv->find(d->anchor);
     1404    const QTextFragmentData * const frag = fragIt.value();
     1405    int fpos = fragIt.position();
     1406    QChar uc = d->priv->buffer().at(d->anchor - fpos + frag->stringPosition);
     1407    if (d->anchor > fpos && uc.unicode() >= 0xdc00 && uc.unicode() < 0xe000) {
     1408        // second half of a surrogate, check if we have the first half as well,
     1409        // if yes delete both at once
     1410        uc = d->priv->buffer().at(d->anchor - 1 - fpos + frag->stringPosition);
     1411        if (uc.unicode() >= 0xd800 && uc.unicode() < 0xdc00)
     1412            --d->anchor;
     1413    }
     1414   
     1415    d->adjusted_anchor = d->anchor;
    13891416    d->remove();
    13901417    d->setX();
     
    15021529        return;
    15031530
     1531    d->priv->beginEditBlock();
    15041532    d->remove();
     1533    d->priv->endEditBlock();
    15051534    d->setX();
    15061535}
     
    18341863
    18351864/*!
     1865    \since 4.6
     1866
    18361867    Returns true if the cursor is at the end of the document;
    18371868    otherwise returns false.
  • trunk/src/gui/text/qtextcursor.h

    r2 r561  
    22**
    33** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
    4 ** Contact: Qt Software Information (qt-info@nokia.com)
     4** All rights reserved.
     5** Contact: Nokia Corporation (qt-info@nokia.com)
    56**
    67** This file is part of the QtGui module of the Qt Toolkit.
     
    2122** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    2223**
    23 ** In addition, as a special exception, Nokia gives you certain
    24 ** additional rights. These rights are described in the Nokia Qt LGPL
    25 ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
    26 ** package.
     24** In addition, as a special exception, Nokia gives you certain additional
     25** rights.  These rights are described in the Nokia Qt LGPL Exception
     26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
    2727**
    2828** GNU General Public License Usage
     
    3434** met: http://www.gnu.org/copyleft/gpl.html.
    3535**
    36 ** If you are unsure which license is appropriate for your use, please
    37 ** contact the sales department at qt-sales@nokia.com.
     36** If you have questions regarding the use of this file, please contact
     37** Nokia at qt-info@nokia.com.
    3838** $QT_END_LICENSE$
    3939**
  • trunk/src/gui/text/qtextcursor_p.h

    r2 r561  
    22**
    33** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
    4 ** Contact: Qt Software Information (qt-info@nokia.com)
     4** All rights reserved.
     5** Contact: Nokia Corporation (qt-info@nokia.com)
    56**
    67** This file is part of the QtGui module of the Qt Toolkit.
     
    2122** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    2223**
    23 ** In addition, as a special exception, Nokia gives you certain
    24 ** additional rights. These rights are described in the Nokia Qt LGPL
    25 ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
    26 ** package.
     24** In addition, as a special exception, Nokia gives you certain additional
     25** rights.  These rights are described in the Nokia Qt LGPL Exception
     26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
    2727**
    2828** GNU General Public License Usage
     
    3434** met: http://www.gnu.org/copyleft/gpl.html.
    3535**
    36 ** If you are unsure which license is appropriate for your use, please
    37 ** contact the sales department at qt-sales@nokia.com.
     36** If you have questions regarding the use of this file, please contact
     37** Nokia at qt-info@nokia.com.
    3838** $QT_END_LICENSE$
    3939**
  • trunk/src/gui/text/qtextdocument.cpp

    r2 r561  
    22**
    33** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
    4 ** Contact: Qt Software Information (qt-info@nokia.com)
     4** All rights reserved.
     5** Contact: Nokia Corporation (qt-info@nokia.com)
    56**
    67** This file is part of the QtGui module of the Qt Toolkit.
     
    2122** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    2223**
    23 ** In addition, as a special exception, Nokia gives you certain
    24 ** additional rights. These rights are described in the Nokia Qt LGPL
    25 ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
    26 ** package.
     24** In addition, as a special exception, Nokia gives you certain additional
     25** rights.  These rights are described in the Nokia Qt LGPL Exception
     26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
    2727**
    2828** GNU General Public License Usage
     
    3434** met: http://www.gnu.org/copyleft/gpl.html.
    3535**
    36 ** If you are unsure which license is appropriate for your use, please
    37 ** contact the sales department at qt-sales@nokia.com.
     36** If you have questions regarding the use of this file, please contact
     37** Nokia at qt-info@nokia.com.
    3838** $QT_END_LICENSE$
    3939**
     
    6565#include "qtextdocument_p.h"
    6666#include <private/qprinter_p.h>
     67#include <private/qabstracttextdocumentlayout_p.h>
    6768
    6869#include <limits.h>
     
    141142/*!
    142143    Converts the plain text string \a plain to a HTML string with
    143     HTML metacharacters \c{<}, \c{>}, and \c{&} replaced by HTML
     144    HTML metacharacters \c{<}, \c{>}, \c{&}, and \c{"} replaced by HTML
    144145    entities.
    145146
     
    163164        else if (plain.at(i) == QLatin1Char('&'))
    164165            rich += QLatin1String("&amp;");
     166        else if (plain.at(i) == QLatin1Char('"'))
     167            rich += QLatin1String("&quot;");
    165168        else
    166169            rich += plain.at(i);
     
    248251    viewed and edited using a QTextEdit.
    249252
    250     \ingroup text
    251     \mainclass
     253    \ingroup richtext-processing
     254
    252255
    253256    QTextDocument is a container for structured rich text documents, providing
     
    288291    system.
    289292
    290     \sa QTextCursor QTextEdit \link richtext.html Rich Text Processing\endlink
     293    \sa QTextCursor, QTextEdit, \link richtext.html Rich Text Processing\endlink , {Text Object Example}
    291294*/
    292295
     
    957960/*!
    958961    Returns true if undo is available; otherwise returns false.
     962
     963    \sa isRedoAvailable(), availableUndoSteps()
    959964*/
    960965bool QTextDocument::isUndoAvailable() const
     
    966971/*!
    967972    Returns true if redo is available; otherwise returns false.
     973
     974    \sa isUndoAvailable(), availableRedoSteps()
    968975*/
    969976bool QTextDocument::isRedoAvailable() const
     
    973980}
    974981
     982/*! \since 4.6
     983
     984    Returns the number of available undo steps.
     985
     986    \sa isUndoAvailable()
     987*/
     988int QTextDocument::availableUndoSteps() const
     989{
     990    Q_D(const QTextDocument);
     991    return d->availableUndoSteps();
     992}
     993
     994/*! \since 4.6
     995
     996    Returns the number of available redo steps.
     997
     998    \sa isRedoAvailable()
     999*/
     1000int QTextDocument::availableRedoSteps() const
     1001{
     1002    Q_D(const QTextDocument);
     1003    return d->availableRedoSteps();
     1004}
    9751005
    9761006/*! \since 4.4
     
    9861016{
    9871017    Q_D(const QTextDocument);
    988     return d->undoState;
     1018    return d->revision;
    9891019}
    9901020
     
    10971127    bool previousState = d->isUndoRedoEnabled();
    10981128    d->enableUndoRedo(false);
     1129    d->beginEditBlock();
    10991130    d->clear();
    11001131    QTextCursor(this).insertText(text);
     1132    d->endEditBlock();
    11011133    d->enableUndoRedo(previousState);
    11021134}
     
    11241156    bool previousState = d->isUndoRedoEnabled();
    11251157    d->enableUndoRedo(false);
     1158    d->beginEditBlock();
    11261159    d->clear();
    11271160    QTextHtmlImporter(this, html, QTextHtmlImporter::ImportToDocument).import();
     1161    d->endEditBlock();
    11281162    d->enableUndoRedo(previousState);
    11291163}
     
    16901724        layout->setPaintDevice(p.device());
    16911725
     1726        // copy the custom object handlers
     1727        layout->d_func()->handlers = documentLayout()->d_func()->handlers;
     1728
    16921729        int dpiy = p.device()->logicalDpiY();
    16931730        int margin = 0;
     
    17301767    fromPage = qMax(1, fromPage);
    17311768    toPage = qMin(doc->pageCount(), toPage);
     1769
     1770    if (toPage < fromPage) {
     1771        // if the user entered a page range outside the actual number
     1772        // of printable pages, just return
     1773        return;
     1774    }
    17321775
    17331776    if (printer->pageOrder() == QPrinter::LastPageFirst) {
     
    20352078    html += QLatin1String(attribute);
    20362079    html += QLatin1String("=\"");
    2037     html += value;
     2080    html += Qt::escape(value);
    20382081    html += QLatin1Char('"');
    20392082}
     
    22022245        html += QLatin1String("%\"");
    22032246    else
    2204         html += QLatin1String("\"");
     2247        html += QLatin1Char('\"');
    22052248}
    22062249
     
    22992342    html += QLatin1String(" font-family:");
    23002343
    2301     QLatin1Char quote('\'');
    2302     if (family.contains(quote))
    2303         quote = QLatin1Char('\"');
     2344    QLatin1String quote("\'");
     2345    if (family.contains(QLatin1Char('\'')))
     2346        quote = QLatin1String("&quot;");
    23042347
    23052348    html += quote;
    2306     html += family;
     2349    html += Qt::escape(family);
    23072350    html += quote;
    23082351    html += QLatin1Char(';');
     
    23382381        if (!name.isEmpty()) {
    23392382            html += QLatin1String("<a name=\"");
    2340             html += name;
     2383            html += Qt::escape(name);
    23412384            html += QLatin1String("\"></a>");
    23422385        }
     
    23442387        if (!href.isEmpty()) {
    23452388            html += QLatin1String("<a href=\"");
    2346             html += href;
     2389            html += Qt::escape(href);
    23472390            html += QLatin1String("\">");
    23482391            closeAnchor = true;
     
    24172460{
    24182461    return style == QTextListFormat::ListDecimal || style == QTextListFormat::ListLowerAlpha
    2419            || style == QTextListFormat::ListUpperAlpha;
     2462           || style == QTextListFormat::ListUpperAlpha
     2463           || style == QTextListFormat::ListUpperRoman
     2464           || style == QTextListFormat::ListLowerRoman
     2465           ;
    24202466}
    24212467
     
    25142560                case QTextListFormat::ListLowerAlpha: html += QLatin1String("<ol type=\"a\""); break;
    25152561                case QTextListFormat::ListUpperAlpha: html += QLatin1String("<ol type=\"A\""); break;
     2562                case QTextListFormat::ListLowerRoman: html += QLatin1String("<ol type=\"i\""); break;
     2563                case QTextListFormat::ListUpperRoman: html += QLatin1String("<ol type=\"I\""); break;
    25162564                default: html += QLatin1String("<ul"); // ### should not happen
    25172565            }
    25182566
     2567            html += QLatin1String(" style=\"margin-top: 0px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px;");
     2568
    25192569            if (format.hasProperty(QTextFormat::ListIndent)) {
    2520                 html += QLatin1String(" style=\"-qt-list-indent: ");
     2570                html += QLatin1String(" -qt-list-indent: ");
    25212571                html += QString::number(format.indent());
    2522                 html += QLatin1String(";\"");
     2572                html += QLatin1Char(';');
    25232573            }
    25242574
    2525             html += QLatin1Char('>');
     2575            html += QLatin1String("\">");
    25262576        }
    25272577
  • trunk/src/gui/text/qtextdocument.h

    r2 r561  
    22**
    33** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
    4 ** Contact: Qt Software Information (qt-info@nokia.com)
     4** All rights reserved.
     5** Contact: Nokia Corporation (qt-info@nokia.com)
    56**
    67** This file is part of the QtGui module of the Qt Toolkit.
     
    2122** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    2223**
    23 ** In addition, as a special exception, Nokia gives you certain
    24 ** additional rights. These rights are described in the Nokia Qt LGPL
    25 ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
    26 ** package.
     24** In addition, as a special exception, Nokia gives you certain additional
     25** rights.  These rights are described in the Nokia Qt LGPL Exception
     26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
    2727**
    2828** GNU General Public License Usage
     
    3434** met: http://www.gnu.org/copyleft/gpl.html.
    3535**
    36 ** If you are unsure which license is appropriate for your use, please
    37 ** contact the sales department at qt-sales@nokia.com.
     36** If you have questions regarding the use of this file, please contact
     37** Nokia at qt-info@nokia.com.
    3838** $QT_END_LICENSE$
    3939**
     
    143143    bool isRedoAvailable() const;
    144144
     145    int availableUndoSteps() const;
     146    int availableRedoSteps() const;
     147
    145148    int revision() const;
    146149
  • trunk/src/gui/text/qtextdocument_p.cpp

    r2 r561  
    22**
    33** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
    4 ** Contact: Qt Software Information (qt-info@nokia.com)
     4** All rights reserved.
     5** Contact: Nokia Corporation (qt-info@nokia.com)
    56**
    67** This file is part of the QtGui module of the Qt Toolkit.
     
    2122** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    2223**
    23 ** In addition, as a special exception, Nokia gives you certain
    24 ** additional rights. These rights are described in the Nokia Qt LGPL
    25 ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
    26 ** package.
     24** In addition, as a special exception, Nokia gives you certain additional
     25** rights.  These rights are described in the Nokia Qt LGPL Exception
     26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
    2727**
    2828** GNU General Public License Usage
     
    3434** met: http://www.gnu.org/copyleft/gpl.html.
    3535**
    36 ** If you are unsure which license is appropriate for your use, please
    37 ** contact the sales department at qt-sales@nokia.com.
     36** If you have questions regarding the use of this file, please contact
     37** Nokia at qt-info@nokia.com.
    3838** $QT_END_LICENSE$
    3939**
     
    6161#define PMDEBUG if(0) qDebug
    6262
     63// The VxWorks DIAB compiler crashes when initializing the anonymouse union with { a7 }
     64#if !defined(Q_CC_DIAB)
     65#  define QT_INIT_TEXTUNDOCOMMAND(c, a1, a2, a3, a4, a5, a6, a7, a8) \
     66          QTextUndoCommand c = { a1, a2, 0, 0, a3, a4, a5, a6, { a7 }, a8 }
     67#else
     68#  define QT_INIT_TEXTUNDOCOMMAND(c, a1, a2, a3, a4, a5, a6, a7, a8) \
     69          QTextUndoCommand c = { a1, a2, 0, 0, a3, a4, a5, a6 }; c.blockFormat = a7; c.revision = a8
     70#endif
     71
    6372/*
    6473  Structure of a document:
     
    180189    docChangeLength(0),
    181190    framesDirty(true),
     191    rtFrame(0),
    182192    initialBlockCharFormatIndex(-1) // set correctly later in init()
    183193{
     
    186196
    187197    undoState = 0;
     198    revision = -1; // init() inserts a block, bringing it to 0
    188199
    189200    lout = 0;
     
    194205    undoEnabled = true;
    195206    inContentsChange = false;
     207
    196208    defaultTextOption.setTabStop(80); // same as in qtextengine.cpp
    197209    defaultTextOption.setWrapMode(QTextOption::WrapAtWordBoundaryOrAnywhere);
     
    208220void QTextDocumentPrivate::init()
    209221{
    210     rtFrame = 0;
    211222    framesDirty = false;
    212223
     
    231242
    232243    QList<QTextCursorPrivate *>oldCursors = cursors;
    233     cursors.clear();
    234     changedCursors.clear();
    235 
    236     QMap<int, QTextObject *>::Iterator objectIt = objects.begin();
    237     while (objectIt != objects.end()) {
    238         if (*objectIt != rtFrame) {
    239             delete *objectIt;
    240             objectIt = objects.erase(objectIt);
    241         } else {
    242             ++objectIt;
     244    QT_TRY{
     245        cursors.clear();
     246        changedCursors.clear();
     247
     248        QMap<int, QTextObject *>::Iterator objectIt = objects.begin();
     249        while (objectIt != objects.end()) {
     250            if (*objectIt != rtFrame) {
     251                delete *objectIt;
     252                objectIt = objects.erase(objectIt);
     253            } else {
     254                ++objectIt;
     255            }
    243256        }
    244     }
    245     // also clear out the remaining root frame pointer
    246     // (we're going to delete the object further down)
    247     objects.clear();
    248 
    249     title.clear();
    250     undoState = 0;
    251     truncateUndoStack();
    252     text = QString();
    253     unreachableCharacterCount = 0;
    254     modifiedState = 0;
    255     modified = false;
    256     formats = QTextFormatCollection();
    257     int len = fragments.length();
    258     fragments.clear();
    259     blocks.clear();
    260     cachedResources.clear();
    261     delete rtFrame;
    262     init();
    263     cursors = oldCursors;
    264     inContentsChange = true;
    265     q->contentsChange(0, len, 0);
    266     inContentsChange = false;
    267     if (lout)
    268         lout->documentChanged(0, len, 0);
     257        // also clear out the remaining root frame pointer
     258        // (we're going to delete the object further down)
     259        objects.clear();
     260
     261        title.clear();
     262        undoState = 0;
     263        truncateUndoStack();
     264        text = QString();
     265        unreachableCharacterCount = 0;
     266        modifiedState = 0;
     267        modified = false;
     268        formats = QTextFormatCollection();
     269        int len = fragments.length();
     270        fragments.clear();
     271        blocks.clear();
     272        cachedResources.clear();
     273        delete rtFrame;
     274        rtFrame = 0;
     275        init();
     276        cursors = oldCursors;
     277        inContentsChange = true;
     278        q->contentsChange(0, len, 0);
     279        inContentsChange = false;
     280        if (lout)
     281            lout->documentChanged(0, len, 0);
     282    } QT_CATCH(...) {
     283        cursors = oldCursors; // at least recover the cursors
     284        QT_RETHROW;
     285    }
    269286}
    270287
     
    405422    QTextBlockData *B = blocks.fragment(b);
    406423
    407     QTextUndoCommand c = { QTextUndoCommand::BlockInserted, true,
    408                            op, charFormat, strPos, pos, { blockFormat },
    409                            B->revision };
     424    QT_INIT_TEXTUNDOCOMMAND(c, QTextUndoCommand::BlockInserted, (editBlock != 0),
     425                            op, charFormat, strPos, pos, blockFormat,
     426                            B->revision);
    410427
    411428    appendUndoItem(c);
     
    413430
    414431    // update revision numbers of the modified blocks.
    415     B->revision = (atBlockEnd && !atBlockStart)? oldRevision : undoState;
     432    B->revision = (atBlockEnd && !atBlockStart)? oldRevision : revision;
    416433    b = blocks.next(b);
    417434    if (b) {
    418435        B = blocks.fragment(b);
    419         B->revision = atBlockStart ? oldRevision : undoState;
     436        B->revision = atBlockStart ? oldRevision : revision;
    420437    }
    421438
     
    440457    Q_ASSERT(formats.format(format).isCharFormat());
    441458
    442     beginEditBlock();
    443459    insert_string(pos, strPos, strLength, format, QTextUndoCommand::MoveCursor);
    444460    if (undoEnabled) {
     
    446462        QTextBlockData *B = blocks.fragment(b);
    447463
    448         QTextUndoCommand c = { QTextUndoCommand::Inserted, true,
    449                                QTextUndoCommand::MoveCursor, format, strPos, pos, { strLength },
    450                                B->revision };
     464        QT_INIT_TEXTUNDOCOMMAND(c, QTextUndoCommand::Inserted, (editBlock != 0),
     465                                QTextUndoCommand::MoveCursor, format, strPos, pos, strLength,
     466                                B->revision);
    451467        appendUndoItem(c);
    452         B->revision = undoState;
     468        B->revision = revision;
    453469        Q_ASSERT(undoState == undoStack.size());
    454470    }
    455     endEditBlock();
     471    finishEdit();
    456472}
    457473
     
    585601#endif
    586602
    587     beginEditBlock();
    588 
    589603    split(pos);
    590604    split(pos+length);
     
    606620
    607621        QTextFragmentData *X = fragments.fragment(x);
    608         QTextUndoCommand c = { QTextUndoCommand::Removed, true,
    609                                op, X->format, X->stringPosition, key, { X->size_array[0] },
    610                                blockRevision };
    611         QTextUndoCommand cInsert = { QTextUndoCommand::Inserted, true,
    612                                      op, X->format, X->stringPosition, dstKey, { X->size_array[0] },
    613                                      blockRevision };
     622        QT_INIT_TEXTUNDOCOMMAND(c, QTextUndoCommand::Removed, (editBlock != 0),
     623                                op, X->format, X->stringPosition, key, X->size_array[0],
     624                                blockRevision);
     625        QT_INIT_TEXTUNDOCOMMAND(cInsert, QTextUndoCommand::Inserted, (editBlock != 0),
     626                                op, X->format, X->stringPosition, dstKey, X->size_array[0],
     627                                blockRevision);
    614628
    615629        if (key+1 != blocks.position(b)) {
     
    638652        appendUndoItem(c);
    639653        if (B)
    640             B->revision = undoState;
     654            B->revision = revision;
    641655        x = n;
    642656
     
    649663    Q_ASSERT(blocks.length() == fragments.length());
    650664
    651     endEditBlock();
     665    finishEdit();
    652666}
    653667
     
    723737        }
    724738
    725         QTextUndoCommand c = { QTextUndoCommand::CharFormatChanged, true, QTextUndoCommand::MoveCursor, oldFormat,
    726                                0, pos, { length }, 0 };
     739        QT_INIT_TEXTUNDOCOMMAND(c, QTextUndoCommand::CharFormatChanged, true, QTextUndoCommand::MoveCursor, oldFormat,
     740                                0, pos, length, 0);
    727741        appendUndoItem(c);
    728742
     
    783797        block(it)->invalidate();
    784798
    785         QTextUndoCommand c = { QTextUndoCommand::BlockFormatChanged, true, QTextUndoCommand::MoveCursor, oldFormat,
    786                                0, it.position(), { 1 }, 0 };
     799        QT_INIT_TEXTUNDOCOMMAND(c, QTextUndoCommand::BlockFormatChanged, true, QTextUndoCommand::MoveCursor, oldFormat,
     800                                0, it.position(), 1, 0);
    787801        appendUndoItem(c);
    788802
     
    857871    undoEnabled = false;
    858872    beginEditBlock();
     873    int editPos = -1;
    859874    while (1) {
    860875        if (undo)
     
    868883            PMDEBUG("   erase: from %d, length %d", c.pos, c.length);
    869884            c.command = QTextUndoCommand::Removed;
     885            editPos = c.pos;
    870886            break;
    871887        case QTextUndoCommand::Removed:
     
    873889            insert_string(c.pos, c.strPos, c.length, c.format, (QTextUndoCommand::Operation)c.operation);
    874890            c.command = QTextUndoCommand::Inserted;
     891            editPos = c.pos + c.length;
    875892            break;
    876893        case QTextUndoCommand::BlockInserted:
     
    882899            else
    883900                c.command = QTextUndoCommand::BlockDeleted;
     901            editPos = c.pos;
    884902            break;
    885903        case QTextUndoCommand::BlockRemoved:
     
    892910            else
    893911                c.command = QTextUndoCommand::BlockAdded;
     912            editPos = c.pos + 1;
    894913            break;
    895914        case QTextUndoCommand::CharFormatChanged: {
     
    902921            setCharFormat(c.pos, c.length, formats.charFormat(c.format));
    903922            c.format = oldFormat;
     923            editPos = c.pos + c.length;
    904924            break;
    905925        }
     
    924944            }
    925945            documentChange(it.position(), it.length());
     946            editPos = -1;
    926947            break;
    927948        }
     
    933954            changeObjectFormat(object, c.format);
    934955            c.format = oldFormat;
     956            editPos = -1;
    935957            break;
    936958        }
     
    941963            else
    942964                c.custom->redo();
     965            editPos = -1;
    943966            break;
    944967        default:
     
    952975        }
    953976
    954         if (undo) {
    955             if (undoState == 0 || !undoStack[undoState-1].block)
    956                 break;
    957         } else {
     977        if (!undo)
    958978            ++undoState;
    959             if (undoState == undoStack.size() || !undoStack[undoState-1].block)
    960                 break;
    961         }
     979
     980        bool inBlock = (
     981                undoState > 0
     982                && undoState < undoStack.size()
     983                && undoStack[undoState].block_part
     984                && undoStack[undoState-1].block_part
     985                && !undoStack[undoState-1].block_end
     986                );
     987        if (!inBlock)
     988            break;
    962989    }
    963990    undoEnabled = true;
    964     int editPos = -1;
    965     if (docChangeFrom >= 0) {
     991    if (editPos < 0 && docChangeFrom >= 0) {
    966992        editPos = qMin(docChangeFrom + docChangeLength, length() - 1);
    967993    }
     
    9841010    QTextUndoCommand c;
    9851011    c.command = QTextUndoCommand::Custom;
    986     c.block = editBlock != 0;
     1012    c.block_part = editBlock != 0;
     1013    c.block_end = 0;
    9871014    c.operation = QTextUndoCommand::MoveCursor;
    9881015    c.format = 0;
     
    10051032    if (!undoStack.isEmpty() && modified) {
    10061033        QTextUndoCommand &last = undoStack[undoState - 1];
    1007         if (last.tryMerge(c))
    1008             return;
     1034
     1035        if ( (last.block_part && c.block_part && !last.block_end) // part of the same block => can merge
     1036            || (!c.block_part && !last.block_part)) {  // two single undo items => can merge
     1037
     1038            if (last.tryMerge(c))
     1039                return;
     1040        }
    10091041    }
    10101042    if (modifiedState > undoState)
     
    10141046    emitUndoAvailable(true);
    10151047    emitRedoAvailable(false);
     1048
     1049    if (!c.block_part)
     1050        emit document()->undoCommandAdded();
    10161051}
    10171052
     
    10781113
    10791114    if (undoEnabled && undoState)
    1080         undoStack[undoState - 1].block = true;
     1115        undoStack[undoState - 1].block_end = false;
    10811116}
    10821117
    10831118void QTextDocumentPrivate::endEditBlock()
    10841119{
     1120    Q_ASSERT(editBlock > 0);
     1121    if (--editBlock)
     1122        return;
     1123
     1124    if (undoEnabled && undoState > 0) {
     1125        const bool wasBlocking = !undoStack[undoState - 1].block_end;
     1126        if (undoStack[undoState - 1].block_part) {
     1127            undoStack[undoState - 1].block_end = true;
     1128            if (wasBlocking)
     1129                emit document()->undoCommandAdded();
     1130        }
     1131    }
     1132
     1133    finishEdit();
     1134}
     1135
     1136void QTextDocumentPrivate::finishEdit()
     1137{
    10851138    Q_Q(QTextDocument);
    1086     if (--editBlock)
    1087         return;
    1088 
    1089     if (undoEnabled && undoState > 0) {
    1090         const bool wasBlocking = undoStack[undoState - 1].block;
    1091         undoStack[undoState - 1].block = false;
    1092         if (wasBlocking)
    1093             emit document()->undoCommandAdded();
    1094     }
     1139
     1140    if (editBlock)
     1141        return;
    10951142
    10961143    if (framesDirty)
     
    11561203    param from is the cursor position in the document
    11571204    param addedOrRemoved is the amount of characters added or removed.  A negative number means characters are removed.
     1205
     1206    The function stores information to be emitted when finishEdit() is called.
    11581207*/
    11591208void QTextDocumentPrivate::adjustDocumentChangesAndCursors(int from, int addedOrRemoved, QTextUndoCommand::Operation op)
    11601209{
    1161     Q_Q(QTextDocument);
     1210    if (!editBlock)
     1211        ++revision;
     1212
    11621213    for (int i = 0; i < cursors.size(); ++i) {
    11631214        QTextCursorPrivate *curs = cursors.at(i);
    11641215        if (curs->adjustPosition(from, addedOrRemoved, op) == QTextCursorPrivate::CursorMoved) {
    1165             if (editBlock) {
    1166                 if (!changedCursors.contains(curs))
    1167                     changedCursors.append(curs);
    1168             } else {
    1169                 emit q->cursorPositionChanged(QTextCursor(curs));
    1170             }
     1216            if (!changedCursors.contains(curs))
     1217                changedCursors.append(curs);
    11711218        }
    11721219    }
     
    11841231//         qDebug("adjustDocumentChanges:");
    11851232//         qDebug("    -> %d %d %d", docChangeFrom, docChangeOldLength, docChangeLength);
    1186         contentsChanged();
    11871233        return;
    11881234    }
     
    12091255//     qDebug("    -> %d %d %d", docChangeFrom, docChangeOldLength, docChangeLength);
    12101256
    1211     contentsChanged();
    12121257}
    12131258
     
    12801325        documentChange(f->firstPosition(), f->lastPosition() - f->firstPosition());
    12811326
    1282     QTextUndoCommand c = { QTextUndoCommand::GroupFormatChange, true, QTextUndoCommand::MoveCursor, oldFormatIndex,
    1283                            0, 0, { obj->d_func()->objectIndex }, 0 };
     1327    QT_INIT_TEXTUNDOCOMMAND(c, QTextUndoCommand::GroupFormatChange, (editBlock != 0), QTextUndoCommand::MoveCursor, oldFormatIndex,
     1328                            0, 0, obj->d_func()->objectIndex, 0);
    12841329    appendUndoItem(c);
    12851330
  • trunk/src/gui/text/qtextdocument_p.h

    r2 r561  
    22**
    33** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
    4 ** Contact: Qt Software Information (qt-info@nokia.com)
     4** All rights reserved.
     5** Contact: Nokia Corporation (qt-info@nokia.com)
    56**
    67** This file is part of the QtGui module of the Qt Toolkit.
     
    2122** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    2223**
    23 ** In addition, as a special exception, Nokia gives you certain
    24 ** additional rights. These rights are described in the Nokia Qt LGPL
    25 ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
    26 ** package.
     24** In addition, as a special exception, Nokia gives you certain additional
     25** rights.  These rights are described in the Nokia Qt LGPL Exception
     26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
    2727**
    2828** GNU General Public License Usage
     
    3434** met: http://www.gnu.org/copyleft/gpl.html.
    3535**
    36 ** If you are unsure which license is appropriate for your use, please
    37 ** contact the sales department at qt-sales@nokia.com.
     36** If you have questions regarding the use of this file, please contact
     37** Nokia at qt-info@nokia.com.
    3838** $QT_END_LICENSE$
    3939**
     
    140140    };
    141141    quint16 command;
    142     quint8 block; ///< All undo commands that have this set to zero/false are combined with the preceding command on undo/redo.
     142    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
     143    uint block_end : 1; // the last command in an undo block has this set to 1.
     144    uint block_padding : 6; // padding since block used to be a quint8
    143145    quint8 operation;
    144146    int format;
     
    200202    inline void redo() { undoRedo(false); }
    201203    void appendUndoItem(QAbstractUndoItem *);
    202     inline void beginEditBlock() { editBlock++; }
     204    inline void beginEditBlock() { if (0 == editBlock++) ++revision; }
    203205    void joinPreviousEditBlock();
    204206    void endEditBlock();
     207    void finishEdit();
    205208    inline bool isInEditBlock() const { return editBlock; }
    206209    void enableUndoRedo(bool enable);
     
    209212    inline bool isUndoAvailable() const { return undoEnabled && undoState > 0; }
    210213    inline bool isRedoAvailable() const { return undoEnabled && undoState < undoStack.size(); }
     214
     215    inline int availableUndoSteps() const { return undoEnabled ? undoState : 0; }
     216    inline int availableRedoSteps() const { return undoEnabled ? qMax(undoStack.size() - undoState - 1, 0) : 0; }
    211217
    212218    inline QString buffer() const { return text; }
     
    303309    bool undoEnabled;
    304310    int undoState;
     311    int revision;
    305312    // position in undo stack of the last setModified(false) call
    306313    int modifiedState;
     
    335342#endif
    336343    int maximumBlockCount;
    337     bool needsEnsureMaximumBlockCount;
    338     bool inContentsChange;
     344    uint needsEnsureMaximumBlockCount : 1;
     345    uint inContentsChange : 1;
    339346    QSizeF pageSize;
    340347    QString title;
  • trunk/src/gui/text/qtextdocumentfragment.cpp

    r2 r561  
    22**
    33** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
    4 ** Contact: Qt Software Information (qt-info@nokia.com)
     4** All rights reserved.
     5** Contact: Nokia Corporation (qt-info@nokia.com)
    56**
    67** This file is part of the QtGui module of the Qt Toolkit.
     
    2122** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    2223**
    23 ** In addition, as a special exception, Nokia gives you certain
    24 ** additional rights. These rights are described in the Nokia Qt LGPL
    25 ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
    26 ** package.
     24** In addition, as a special exception, Nokia gives you certain additional
     25** rights.  These rights are described in the Nokia Qt LGPL Exception
     26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
    2727**
    2828** GNU General Public License Usage
     
    3434** met: http://www.gnu.org/copyleft/gpl.html.
    3535**
    36 ** If you are unsure which license is appropriate for your use, please
    37 ** contact the sales department at qt-sales@nokia.com.
     36** If you have questions regarding the use of this file, please contact
     37** Nokia at qt-info@nokia.com.
    3838** $QT_END_LICENSE$
    3939**
     
    5555
    5656QTextCopyHelper::QTextCopyHelper(const QTextCursor &_source, const QTextCursor &_destination, bool forceCharFormat, const QTextCharFormat &fmt)
     57#if defined(Q_CC_DIAB) // compiler bug
     58    : formatCollection(*_destination.d->priv->formatCollection()), originalText((const QString)_source.d->priv->buffer())
     59#else
    5760    : formatCollection(*_destination.d->priv->formatCollection()), originalText(_source.d->priv->buffer())
     61#endif
    5862{
    5963    src = _source.d->priv;
     
    256260    from a QTextDocument.
    257261
    258     \ingroup text
     262    \ingroup richtext-processing
    259263    \ingroup shared
    260264
  • trunk/src/gui/text/qtextdocumentfragment.h

    r2 r561  
    22**
    33** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
    4 ** Contact: Qt Software Information (qt-info@nokia.com)
     4** All rights reserved.
     5** Contact: Nokia Corporation (qt-info@nokia.com)
    56**
    67** This file is part of the QtGui module of the Qt Toolkit.
     
    2122** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    2223**
    23 ** In addition, as a special exception, Nokia gives you certain
    24 ** additional rights. These rights are described in the Nokia Qt LGPL
    25 ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
    26 ** package.
     24** In addition, as a special exception, Nokia gives you certain additional
     25** rights.  These rights are described in the Nokia Qt LGPL Exception
     26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
    2727**
    2828** GNU General Public License Usage
     
    3434** met: http://www.gnu.org/copyleft/gpl.html.
    3535**
    36 ** If you are unsure which license is appropriate for your use, please
    37 ** contact the sales department at qt-sales@nokia.com.
     36** If you have questions regarding the use of this file, please contact
     37** Nokia at qt-info@nokia.com.
    3838** $QT_END_LICENSE$
    3939**
  • trunk/src/gui/text/qtextdocumentfragment_p.h

    r2 r561  
    22**
    33** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
    4 ** Contact: Qt Software Information (qt-info@nokia.com)
     4** All rights reserved.
     5** Contact: Nokia Corporation (qt-info@nokia.com)
    56**
    67** This file is part of the QtGui module of the Qt Toolkit.
     
    2122** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    2223**
    23 ** In addition, as a special exception, Nokia gives you certain
    24 ** additional rights. These rights are described in the Nokia Qt LGPL
    25 ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
    26 ** package.
     24** In addition, as a special exception, Nokia gives you certain additional
     25** rights.  These rights are described in the Nokia Qt LGPL Exception
     26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
    2727**
    2828** GNU General Public License Usage
     
    3434** met: http://www.gnu.org/copyleft/gpl.html.
    3535**
    36 ** If you are unsure which license is appropriate for your use, please
    37 ** contact the sales department at qt-sales@nokia.com.
     36** If you have questions regarding the use of this file, please contact
     37** Nokia at qt-info@nokia.com.
    3838** $QT_END_LICENSE$
    3939**
  • trunk/src/gui/text/qtextdocumentlayout.cpp

    r2 r561  
    22**
    33** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
    4 ** Contact: Qt Software Information (qt-info@nokia.com)
     4** All rights reserved.
     5** Contact: Nokia Corporation (qt-info@nokia.com)
    56**
    67** This file is part of the QtGui module of the Qt Toolkit.
     
    2122** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    2223**
    23 ** In addition, as a special exception, Nokia gives you certain
    24 ** additional rights. These rights are described in the Nokia Qt LGPL
    25 ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
    26 ** package.
     24** In addition, as a special exception, Nokia gives you certain additional
     25** rights.  These rights are described in the Nokia Qt LGPL Exception
     26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
    2727**
    2828** GNU General Public License Usage
     
    3434** met: http://www.gnu.org/copyleft/gpl.html.
    3535**
    36 ** If you are unsure which license is appropriate for your use, please
    37 ** contact the sales department at qt-sales@nokia.com.
     36** If you have questions regarding the use of this file, please contact
     37** Nokia at qt-info@nokia.com.
    3838** $QT_END_LICENSE$
    3939**
     
    199199            return cellPadding;
    200200        } else {
    201             Q_ASSERT(v.type() == QVariant::Double);
    202             return QFixed::fromReal(v.toDouble() * deviceScale);
     201            Q_ASSERT(v.userType() == QVariant::Double || v.userType() == QMetaType::Float);
     202            return QFixed::fromReal(v.toReal() * deviceScale);
    203203        }
    204204    }
     
    856856void QTextDocumentLayoutPrivate::drawFrameDecoration(QPainter *painter, QTextFrame *frame, QTextFrameData *fd, const QRectF &clip, const QRectF &rect) const
    857857{
     858
     859    const QBrush bg = frame->frameFormat().background();
     860    if (bg != Qt::NoBrush) {
     861        QRectF bgRect = rect;
     862        bgRect.adjust((fd->leftMargin + fd->border).toReal(),
     863                      (fd->topMargin + fd->border).toReal(),
     864                      - (fd->rightMargin + fd->border).toReal(),
     865                      - (fd->bottomMargin + fd->border).toReal());
     866
     867        QRectF gradientRect; // invalid makes it default to bgRect
     868        QPointF origin = bgRect.topLeft();
     869        if (!frame->parentFrame()) {
     870            bgRect = clip;
     871            gradientRect.setWidth(painter->device()->width());
     872            gradientRect.setHeight(painter->device()->height());
     873        }
     874        fillBackground(painter, bgRect, bg, origin, gradientRect);
     875    }
    858876    if (fd->border != 0) {
    859877        painter->save();
     
    875893
    876894        painter->restore();
    877     }
    878 
    879     const QBrush bg = frame->frameFormat().background();
    880     if (bg != Qt::NoBrush) {
    881         QRectF bgRect = rect;
    882         bgRect.adjust((fd->leftMargin + fd->border).toReal(),
    883                       (fd->topMargin + fd->border).toReal(),
    884                       - (fd->rightMargin + fd->border).toReal(),
    885                       - (fd->bottomMargin + fd->border).toReal());
    886 
    887         QRectF gradientRect; // invalid makes it default to bgRect
    888         QPointF origin = bgRect.topLeft();
    889         if (!frame->parentFrame()) {
    890             bgRect = clip;
    891             gradientRect.setWidth(painter->device()->width());
    892             gradientRect.setHeight(painter->device()->height());
    893         }
    894         fillBackground(painter, bgRect, bg, origin, gradientRect);
    895895    }
    896896}
     
    13841384    case QTextListFormat::ListLowerAlpha:
    13851385    case QTextListFormat::ListUpperAlpha:
     1386    case QTextListFormat::ListLowerRoman:
     1387    case QTextListFormat::ListUpperRoman:
    13861388        itemText = static_cast<QTextList *>(object)->itemText(bl);
    13871389        size.setWidth(fontMetrics.width(itemText));
     
    14271429    case QTextListFormat::ListDecimal:
    14281430    case QTextListFormat::ListLowerAlpha:
    1429     case QTextListFormat::ListUpperAlpha: {
     1431    case QTextListFormat::ListUpperAlpha:
     1432    case QTextListFormat::ListLowerRoman:
     1433    case QTextListFormat::ListUpperRoman: {
    14301434        QTextLayout layout(itemText, font, q->paintDevice());
    14311435        layout.setCacheEnabled(true);
     
    14341438        layout.setTextOption(option);
    14351439        layout.beginLayout();
    1436         layout.createLine();
     1440        QTextLine line = layout.createLine();
     1441        if (line.isValid())
     1442            line.setLeadingIncluded(true);
    14371443        layout.endLayout();
    14381444        layout.draw(painter, QPointF(r.left(), pos.y()));
     
    14431449        break;
    14441450    case QTextListFormat::ListCircle:
    1445         painter->drawEllipse(r);
     1451        painter->setPen(QPen(brush, 0));
     1452        painter->drawEllipse(r.translated(0.5, 0.5)); // pixel align for sharper rendering
    14461453        break;
    14471454    case QTextListFormat::ListDisc:
     
    14491456        painter->setPen(Qt::NoPen);
    14501457        painter->drawEllipse(r);
    1451         painter->setBrush(Qt::NoBrush);
    14521458        break;
    14531459    case QTextListFormat::ListStyleUndefined:
     
    19911997    }
    19921998
    1993     if (y + layoutStruct->frameY + fd->size.height > layoutStruct->pageBottom) {
     1999    bool frameSpansIntoNextPage = (y + layoutStruct->frameY + fd->size.height > layoutStruct->pageBottom);
     2000    if (frameSpansIntoNextPage && fd->size.height <= layoutStruct->pageHeight) {
    19942001        layoutStruct->newPage();
    19952002        y = layoutStruct->y;
     2003
     2004        frameSpansIntoNextPage = false;
    19962005    }
    19972006
     
    20142023//     qDebug()<< "float positioned at " << fd->position.x << fd->position.y;
    20152024    fd->layoutDirty = false;
     2025
     2026    // If the frame is a table, then positioning it will affect the size if it covers more than
     2027    // one page, because of page breaks and repeating the header.
     2028    if (qobject_cast<QTextTable *>(frame) != 0)
     2029        fd->sizeDirty = frameSpansIntoNextPage;
    20162030}
    20172031
     
    23452359
    23462360                positionFloat(c);
     2361
     2362                // If the size was made dirty when the position was set, layout again
     2363                if (cd->sizeDirty)
     2364                    updateRect = layoutFrame(c, layoutFrom, layoutTo);
    23472365
    23482366                QRectF frameRect(cd->position.toPointF(), cd->size.toSizeF());
     
    25012519    LDEBUG << "layoutBlock from=" << layoutFrom << "to=" << layoutTo;
    25022520
    2503 //    qDebug() << "layoutBlock; width" << layoutStruct->x_right - layoutStruct->x_left << "(maxWidth is btw" << tl->maximumWidth() << ")";
     2521//    qDebug() << "layoutBlock; width" << layoutStruct->x_right - layoutStruct->x_left << "(maxWidth is btw" << tl->maximumWidth() << ')';
    25042522
    25052523    if (previousBlockFormat) {
     
    25642582            if (!line.isValid())
    25652583                break;
     2584            line.setLeadingIncluded(true);
    25662585
    25672586            QFixed left, right;
     
    25982617                layoutStruct->pendingFloats.clear();
    25992618
    2600                 if (haveWordOrAnyWrapMode) {
    2601                     option.setWrapMode(QTextOption::WrapAnywhere);
    2602                     tl->setTextOption(option);
    2603                 }
    2604 
    26052619                line.setLineWidth((right-left).toReal());
    26062620                if (QFixed::fromReal(line.naturalTextWidth()) > right-left) {
     2621                    if (haveWordOrAnyWrapMode) {
     2622                        option.setWrapMode(QTextOption::WrapAnywhere);
     2623                        tl->setTextOption(option);
     2624                    }
     2625
    26072626                    layoutStruct->pendingFloats.clear();
    26082627                    // lines min width more than what we have
     
    26162635                        right -= text_indent;
    26172636                    line.setLineWidth(qMax<qreal>(line.naturalTextWidth(), (right-left).toReal()));
     2637
     2638                    if (haveWordOrAnyWrapMode) {
     2639                        option.setWrapMode(QTextOption::WordWrap);
     2640                        tl->setTextOption(option);
     2641                    }
    26182642                }
    26192643
    2620                 if (haveWordOrAnyWrapMode) {
    2621                     option.setWrapMode(QTextOption::WordWrap);
    2622                     tl->setTextOption(option);
    2623                 }
    26242644            }
    26252645
     
    32063226qreal QTextDocumentLayoutPrivate::scaleToDevice(qreal value) const
    32073227{
    3208     QPaintDevice *dev = q_func()->paintDevice();
    3209     if (!dev)
     3228    if (!paintDevice)
    32103229        return value;
    3211     return value * dev->logicalDpiY() / qreal(qt_defaultDpi());
     3230    return value * paintDevice->logicalDpiY() / qreal(qt_defaultDpi());
    32123231}
    32133232
    32143233QFixed QTextDocumentLayoutPrivate::scaleToDevice(QFixed value) const
    32153234{
    3216     QPaintDevice *dev = q_func()->paintDevice();
    3217     if (!dev)
     3235    if (!paintDevice)
    32183236        return value;
    3219     return value * QFixed(dev->logicalDpiY()) / QFixed(qt_defaultDpi());
     3237    return value * QFixed(paintDevice->logicalDpiY()) / QFixed(qt_defaultDpi());
    32203238}
    32213239
  • trunk/src/gui/text/qtextdocumentlayout_p.h

    r2 r561  
    22**
    33** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
    4 ** Contact: Qt Software Information (qt-info@nokia.com)
     4** All rights reserved.
     5** Contact: Nokia Corporation (qt-info@nokia.com)
    56**
    67** This file is part of the QtGui module of the Qt Toolkit.
     
    2122** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    2223**
    23 ** In addition, as a special exception, Nokia gives you certain
    24 ** additional rights. These rights are described in the Nokia Qt LGPL
    25 ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
    26 ** package.
     24** In addition, as a special exception, Nokia gives you certain additional
     25** rights.  These rights are described in the Nokia Qt LGPL Exception
     26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
    2727**
    2828** GNU General Public License Usage
     
    3434** met: http://www.gnu.org/copyleft/gpl.html.
    3535**
    36 ** If you are unsure which license is appropriate for your use, please
    37 ** contact the sales department at qt-sales@nokia.com.
     36** If you have questions regarding the use of this file, please contact
     37** Nokia at qt-info@nokia.com.
    3838** $QT_END_LICENSE$
    3939**
  • trunk/src/gui/text/qtextdocumentwriter.cpp

    r2 r561  
    22**
    33** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
    4 ** Contact: Qt Software Information (qt-info@nokia.com)
     4** All rights reserved.
     5** Contact: Nokia Corporation (qt-info@nokia.com)
    56**
    67** This file is part of the QtGui module of the Qt Toolkit.
     
    2122** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    2223**
    23 ** In addition, as a special exception, Nokia gives you certain
    24 ** additional rights. These rights are described in the Nokia Qt LGPL
    25 ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
    26 ** package.
     24** In addition, as a special exception, Nokia gives you certain additional
     25** rights.  These rights are described in the Nokia Qt LGPL Exception
     26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
    2727**
    2828** GNU General Public License Usage
     
    3434** met: http://www.gnu.org/copyleft/gpl.html.
    3535**
    36 ** If you are unsure which license is appropriate for your use, please
    37 ** contact the sales department at qt-sales@nokia.com.
     36** If you have questions regarding the use of this file, please contact
     37** Nokia at qt-info@nokia.com.
    3838** $QT_END_LICENSE$
    3939**
     
    7777    \brief The QTextDocumentWriter class provides a format-independent interface for writing a QTextDocument to files or other devices.
    7878
    79     \ingroup text
     79    \ingroup richtext-processing
    8080    \ingroup io
    8181
  • trunk/src/gui/text/qtextdocumentwriter.h

    r2 r561  
    22**
    33** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
    4 ** Contact: Qt Software Information (qt-info@nokia.com)
     4** All rights reserved.
     5** Contact: Nokia Corporation (qt-info@nokia.com)
    56**
    67** This file is part of the QtGui module of the Qt Toolkit.
     
    2122** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    2223**
    23 ** In addition, as a special exception, Nokia gives you certain
    24 ** additional rights. These rights are described in the Nokia Qt LGPL
    25 ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
    26 ** package.
     24** In addition, as a special exception, Nokia gives you certain additional
     25** rights.  These rights are described in the Nokia Qt LGPL Exception
     26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
    2727**
    2828** GNU General Public License Usage
     
    3434** met: http://www.gnu.org/copyleft/gpl.html.
    3535**
    36 ** If you are unsure which license is appropriate for your use, please
    37 ** contact the sales department at qt-sales@nokia.com.
     36** If you have questions regarding the use of this file, please contact
     37** Nokia at qt-info@nokia.com.
    3838** $QT_END_LICENSE$
    3939**
  • trunk/src/gui/text/qtextengine.cpp

    r2 r561  
    22**
    33** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
    4 ** Contact: Qt Software Information (qt-info@nokia.com)
     4** All rights reserved.
     5** Contact: Nokia Corporation (qt-info@nokia.com)
    56**
    67** This file is part of the QtGui module of the Qt Toolkit.
     
    2122** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    2223**
    23 ** In addition, as a special exception, Nokia gives you certain
    24 ** additional rights. These rights are described in the Nokia Qt LGPL
    25 ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
    26 ** package.
     24** In addition, as a special exception, Nokia gives you certain additional
     25** rights.  These rights are described in the Nokia Qt LGPL Exception
     26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
    2727**
    2828** GNU General Public License Usage
     
    3434** met: http://www.gnu.org/copyleft/gpl.html.
    3535**
    36 ** If you are unsure which license is appropriate for your use, please
    37 ** contact the sales department at qt-sales@nokia.com.
     36** If you have questions regarding the use of this file, please contact
     37** Nokia at qt-info@nokia.com.
    3838** $QT_END_LICENSE$
    3939**
     
    364364//         qDebug() << "pos=" << current << " dir=" << directions[dir]
    365365//                  << " current=" << directions[dirCurrent] << " last=" << directions[status.last]
    366 //                  << " eor=" << eor << "/" << directions[status.eor]
     366//                  << " eor=" << eor << '/' << directions[status.eor]
    367367//                  << " sor=" << sor << " lastStrong="
    368368//                  << directions[status.lastStrong]
     
    869869#if defined(Q_WS_MAC)
    870870    shapeTextMac(item);
    871 #elif defined(Q_OS_WINCE)
     871#elif defined(Q_WS_WINCE)
    872872    shapeTextWithCE(item);
    873873#else
     
    924924}
    925925
    926 #if defined(Q_OS_WINCE) //TODO
     926#if defined(Q_WS_WINCE) //TODO
    927927// set the glyph attributes heuristically. Assumes a 1 to 1 relationship between chars and glyphs
    928928// and no reordering.
     
    10431043    si.glyph_data_offset = layoutData->used;
    10441044
    1045     QFontEngine *fe = fontEngine(si, &si.ascent, &si.descent);
     1045    QFontEngine *fe = fontEngine(si, &si.ascent, &si.descent, &si.leading);
    10461046
    10471047    QTextEngine::ShaperFlags flags;
     
    11001100#endif
    11011101
     1102static inline void moveGlyphData(const QGlyphLayout &destination, const QGlyphLayout &source, int num)
     1103{
     1104    if (num > 0 && destination.glyphs != source.glyphs) {
     1105        memmove(destination.glyphs, source.glyphs, num * sizeof(HB_Glyph));
     1106        memmove(destination.attributes, source.attributes, num * sizeof(HB_GlyphAttributes));
     1107        memmove(destination.advances_x, source.advances_x, num * sizeof(HB_Fixed));
     1108        memmove(destination.offsets, source.offsets, num * sizeof(HB_FixedPoint));
     1109    }
     1110}
     1111
    11021112/// take the item from layoutData->items and
    11031113void QTextEngine::shapeTextWithHarfbuzz(int item) const
     
    11101120    si.glyph_data_offset = layoutData->used;
    11111121
    1112     QFontEngine *font = fontEngine(si, &si.ascent, &si.descent);
     1122    QFontEngine *font = fontEngine(si, &si.ascent, &si.descent, &si.leading);
    11131123
    11141124    bool kerningEnabled = this->font(si).d->kerning;
     
    11901200
    11911201
    1192     int initial_glyph_pos = 0;
     1202    int remaining_glyphs = entire_shaper_item.num_glyphs;
    11931203    int glyph_pos = 0;
    11941204    // for each item shape using harfbuzz and store the results in our layoutData's glyphs array.
     
    12101220        uint engineIdx = 0;
    12111221        if (font->type() == QFontEngine::Multi) {
    1212             engineIdx = uint(initialGlyphs.glyphs[itemBoundaries[k + 1]] >> 24);
     1222            engineIdx = uint(availableGlyphs(&si).glyphs[glyph_pos] >> 24);
    12131223
    12141224            actualFontEngine = static_cast<QFontEngineMulti *>(font)->engine(engineIdx);
     
    12201230        shaper_item.glyphIndicesPresent = true;
    12211231
     1232        remaining_glyphs -= shaper_item.initialGlyphCount;
     1233
    12221234        do {
    1223             ensureSpace(glyph_pos + shaper_item.num_glyphs);
    1224             initialGlyphs = availableGlyphs(&si).mid(0, entire_shaper_item.num_glyphs);
    1225             shaper_item.num_glyphs = layoutData->glyphLayout.numGlyphs - layoutData->used - glyph_pos;
    1226 
    1227             const QGlyphLayout g = availableGlyphs(&si);
    1228             shaper_item.glyphs = g.glyphs + glyph_pos;
    1229             shaper_item.attributes = g.attributes + glyph_pos;
    1230             shaper_item.advances = reinterpret_cast<HB_Fixed *>(g.advances_x + glyph_pos);
    1231             shaper_item.offsets = reinterpret_cast<HB_FixedPoint *>(g.offsets + glyph_pos);
     1235            ensureSpace(glyph_pos + shaper_item.num_glyphs + remaining_glyphs);
     1236
     1237            const QGlyphLayout g = availableGlyphs(&si).mid(glyph_pos);
     1238            moveGlyphData(g.mid(shaper_item.num_glyphs), g.mid(shaper_item.initialGlyphCount), remaining_glyphs);
     1239
     1240            shaper_item.glyphs = g.glyphs;
     1241            shaper_item.attributes = g.attributes;
     1242            shaper_item.advances = reinterpret_cast<HB_Fixed *>(g.advances_x);
     1243            shaper_item.offsets = reinterpret_cast<HB_FixedPoint *>(g.offsets);
    12321244
    12331245            if (shaper_item.glyphIndicesPresent) {
     
    12421254
    12431255        QGlyphLayout g = availableGlyphs(&si).mid(glyph_pos, shaper_item.num_glyphs);
    1244 
    1245         for (hb_uint32 i = 0; i < shaper_item.item.length; ++i) {
     1256        moveGlyphData(g.mid(shaper_item.num_glyphs), g.mid(shaper_item.initialGlyphCount), remaining_glyphs);
     1257
     1258        for (hb_uint32 i = 0; i < shaper_item.num_glyphs; ++i)
    12461259            g.glyphs[i] = g.glyphs[i] | (engineIdx << 24);
     1260
     1261        for (hb_uint32 i = 0; i < shaper_item.item.length; ++i)
    12471262            shaper_item.log_clusters[i] += glyph_pos;
    1248         }
    12491263
    12501264        if (kerningEnabled && !shaper_item.kerning_applied)
     
    12521266
    12531267        glyph_pos += shaper_item.num_glyphs;
    1254 
    1255         initial_glyph_pos += shaper_item.initialGlyphCount;
    12561268    }
    12571269
     
    13391351        }
    13401352    } else if (layoutData->items[item].analysis.flags == QScriptAnalysis::Tab) {
    1341         // set up at least the ascent/descent of the script item for the tab
    1342         fontEngine(layoutData->items[item], &layoutData->items[item].ascent, &layoutData->items[item].descent);
     1353        // set up at least the ascent/descent/leading of the script item for the tab
     1354        fontEngine(layoutData->items[item],
     1355                   &layoutData->items[item].ascent,
     1356                   &layoutData->items[item].descent,
     1357                   &layoutData->items[item].leading);
    13431358    } else {
    13441359        shapeText(item);
     
    13851400    if (!length)
    13861401        return;
    1387 
     1402#if defined(Q_WS_MAC) && !defined(QT_MAC_USE_COCOA)
     1403    // ATSUI requires RTL flags to correctly identify the character stops.
     1404    bool ignore = false;
     1405#else
    13881406    bool ignore = ignoreBidi;
     1407#endif
    13891408    if (!ignore && option.textDirection() == Qt::LeftToRight) {
    13901409        ignore = true;
     
    15831602    for (int i = 0; i < layoutData->items.size(); i++) {
    15841603        const QScriptItem *si = layoutData->items.constData() + i;
     1604        QFontEngine *fe = fontEngine(*si);
     1605
    15851606        int pos = si->position;
    15861607        int ilen = length(i);
    15871608        if (pos > from + len)
    15881609            break;
    1589         if (pos + len > from) {
     1610        if (pos + ilen > from) {
    15901611            if (!si->num_glyphs)
    15911612                shape(i);
     
    16201641                glyphEnd = (charEnd == ilen) ? si->num_glyphs : logClusters[charEnd];
    16211642                if (glyphStart <= glyphEnd ) {
    1622                     QFontEngine *fe = fontEngine(*si);
    16231643                    glyph_metrics_t m = fe->boundingBox(glyphs.mid(glyphStart, glyphEnd - glyphStart));
    16241644                    gm.x = qMin(gm.x, m.x + gm.xoff);
     
    16301650                }
    16311651            }
     1652
     1653            glyph_t glyph = glyphs.glyphs[logClusters[pos + ilen - 1]];
     1654            glyph_metrics_t gi = fe->boundingBox(glyph);
     1655            if (gi.isValid())
     1656                gm.width -= qRound(gi.xoff - gi.x - gi.width);
    16321657        }
    16331658    }
     
    17161741}
    17171742
    1718 QFontEngine *QTextEngine::fontEngine(const QScriptItem &si, QFixed *ascent, QFixed *descent) const
     1743QFontEngine *QTextEngine::fontEngine(const QScriptItem &si, QFixed *ascent, QFixed *descent, QFixed *leading) const
    17191744{
    17201745    QFontEngine *engine = 0;
     
    17561781        *ascent = engine->ascent();
    17571782        *descent = engine->descent();
     1783        *leading = engine->leading();
    17581784    }
    17591785
     
    19882014    }
    19892015
    1990     ascent = qMax(ascent, e->ascent());
    1991     descent = qMax(descent, e->descent());
     2016    QFixed other_ascent = e->ascent();
     2017    QFixed other_descent = e->descent();
     2018    QFixed other_leading = e->leading();
     2019    leading = qMax(leading + ascent, other_leading + other_ascent) - qMax(ascent, other_ascent);
     2020    ascent = qMax(ascent, other_ascent);
     2021    descent = qMax(descent, other_descent);
    19922022}
    19932023
     
    20582088    int newAllocated = space_charAttributes + space_glyphs + space_logClusters;
    20592089    Q_ASSERT(newAllocated >= allocated);
    2060     void **old_mem = memory;
    2061     memory = (void **)::realloc(memory_on_stack ? 0 : old_mem, newAllocated*sizeof(void *));
    2062     if (memory_on_stack && memory)
    2063         memcpy(memory, old_mem, allocated*sizeof(void *));
     2090    void **newMem = memory;
     2091    newMem = (void **)::realloc(memory_on_stack ? 0 : memory, newAllocated*sizeof(void *));
     2092    Q_CHECK_PTR(newMem);
     2093    if (memory_on_stack && newMem)
     2094        memcpy(newMem, memory, allocated*sizeof(void *));
     2095    memory = newMem;
    20642096    memory_on_stack = false;
    20652097
     
    21992231    case '"':
    22002232    case '~':
     2233    case '|':
    22012234        return true;
    22022235    default:
     
    22292262        specialData->addFormats[i].format = QTextCharFormat();
    22302263    }
     2264}
     2265
     2266/* These two helper functions are used to determine whether we need to insert a ZWJ character
     2267   between the text that gets truncated and the ellipsis. This is important to get
     2268   correctly shaped results for arabic text.
     2269*/
     2270static bool nextCharJoins(const QString &string, int pos)
     2271{
     2272    while (pos < string.length() && string.at(pos).category() == QChar::Mark_NonSpacing)
     2273        ++pos;
     2274    if (pos == string.length())
     2275        return false;
     2276    return string.at(pos).joining() != QChar::OtherJoining;
     2277}
     2278
     2279static bool prevCharJoins(const QString &string, int pos)
     2280{
     2281    while (pos > 0 && string.at(pos - 1).category() == QChar::Mark_NonSpacing)
     2282        --pos;
     2283    if (pos == 0)
     2284        return false;
     2285    return (string.at(pos - 1).joining() == QChar::Dual || string.at(pos - 1).joining() == QChar::Center);
    22312286}
    22322287
     
    23312386                 && currentWidth < availableWidth);
    23322387
     2388        if (nextCharJoins(layoutData->string, pos))
     2389            ellipsisText.prepend(QChar(0x200d) /* ZWJ */);
     2390
    23332391        return layoutData->string.left(pos) + ellipsisText;
    23342392    } else if (mode == Qt::ElideLeft) {
     
    23482406                 && currentWidth < availableWidth);
    23492407
     2408        if (prevCharJoins(layoutData->string, pos))
     2409            ellipsisText.append(QChar(0x200d) /* ZWJ */);
     2410
    23502411        return ellipsisText + layoutData->string.mid(pos);
    23512412    } else if (mode == Qt::ElideMiddle) {
     
    23762437                 && nextRightBreak > 0
    23772438                 && leftWidth + rightWidth < availableWidth);
     2439
     2440        if (nextCharJoins(layoutData->string, leftPos))
     2441            ellipsisText.prepend(QChar(0x200d) /* ZWJ */);
     2442        if (prevCharJoins(layoutData->string, rightPos))
     2443            ellipsisText.append(QChar(0x200d) /* ZWJ */);
    23782444
    23792445        return layoutData->string.left(leftPos) + ellipsisText + layoutData->string.mid(rightPos);
  • trunk/src/gui/text/qtextengine_mac.cpp

    r2 r561  
    22**
    33** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
    4 ** Contact: Qt Software Information (qt-info@nokia.com)
     4** All rights reserved.
     5** Contact: Nokia Corporation (qt-info@nokia.com)
    56**
    67** This file is part of the QtGui module of the Qt Toolkit.
     
    2122** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    2223**
    23 ** In addition, as a special exception, Nokia gives you certain
    24 ** additional rights. These rights are described in the Nokia Qt LGPL
    25 ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
    26 ** package.
     24** In addition, as a special exception, Nokia gives you certain additional
     25** rights.  These rights are described in the Nokia Qt LGPL Exception
     26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
    2727**
    2828** GNU General Public License Usage
     
    3434** met: http://www.gnu.org/copyleft/gpl.html.
    3535**
    36 ** If you are unsure which license is appropriate for your use, please
    37 ** contact the sales department at qt-sales@nokia.com.
     36** If you have questions regarding the use of this file, please contact
     37** Nokia at qt-info@nokia.com.
    3838** $QT_END_LICENSE$
    3939**
     
    5151    // ### zeroWidth and justification are missing here!!!!!
    5252
    53     Q_ASSERT(num_glyphs <= length);
    5453    Q_UNUSED(num_glyphs);
    5554
     
    559558    si.glyph_data_offset = layoutData->used;
    560559
    561     QFontEngine *font = fontEngine(si, &si.ascent, &si.descent);
     560    QFontEngine *font = fontEngine(si, &si.ascent, &si.descent, &si.leading);
    562561    if (font->type() != QFontEngine::Multi) {
    563562        shapeTextWithHarfbuzz(item);
     
    596595    }
    597596
    598     while (true) {
    599         ensureSpace(num_glyphs);
    600         num_glyphs = layoutData->glyphLayout.numGlyphs - layoutData->used;
    601 
    602         QGlyphLayout g = availableGlyphs(&si);
    603         g.numGlyphs = num_glyphs;
    604         unsigned short *log_clusters = logClusters(&si);
    605 
    606         if (fe->stringToCMap(str,
    607                              len,
    608                              &g,
    609                              &num_glyphs,
    610                              flags,
    611                              log_clusters,
    612                              attributes())) {
    613 
    614                 heuristicSetGlyphAttributes(str, len, &g, log_clusters, num_glyphs);
    615                 break;
    616         }
     597    ensureSpace(num_glyphs);
     598    num_glyphs = layoutData->glyphLayout.numGlyphs - layoutData->used;
     599
     600    QGlyphLayout g = availableGlyphs(&si);
     601    g.numGlyphs = num_glyphs;
     602    unsigned short *log_clusters = logClusters(&si);
     603
     604    bool stringToCMapFailed = false;
     605    if (!fe->stringToCMap(str, len, &g, &num_glyphs, flags, log_clusters, attributes())) {
     606        ensureSpace(num_glyphs);
     607        stringToCMapFailed = fe->stringToCMap(str, len, &g, &num_glyphs, flags, log_clusters,
     608                                              attributes());
    617609    }
    618610
    619     si.num_glyphs = num_glyphs;
    620 
    621     layoutData->used += si.num_glyphs;
    622 
    623     QGlyphLayout g = shapedGlyphs(&si);
    624 
    625     if (si.analysis.script == QUnicodeTables::Arabic) {
    626         QVarLengthArray<QArabicProperties> props(len + 2);
    627         QArabicProperties *properties = props.data();
    628         int f = si.position;
    629         int l = len;
    630         if (f > 0) {
    631             --f;
    632             ++l;
    633             ++properties;
    634         }
    635         if (f + l < layoutData->string.length()) {
    636             ++l;
    637         }
    638         qt_getArabicProperties((const unsigned short *)(layoutData->string.unicode()+f), l, props.data());
    639 
    640         unsigned short *log_clusters = logClusters(&si);
    641 
    642         for (int i = 0; i < len; ++i) {
    643             int gpos = log_clusters[i];
    644             g.attributes[gpos].justification = properties[i].justification;
     611    if (!stringToCMapFailed) {
     612        heuristicSetGlyphAttributes(str, len, &g, log_clusters, num_glyphs);
     613
     614        si.num_glyphs = num_glyphs;
     615
     616        layoutData->used += si.num_glyphs;
     617
     618        QGlyphLayout g = shapedGlyphs(&si);
     619
     620        if (si.analysis.script == QUnicodeTables::Arabic) {
     621            QVarLengthArray<QArabicProperties> props(len + 2);
     622            QArabicProperties *properties = props.data();
     623            int f = si.position;
     624            int l = len;
     625            if (f > 0) {
     626                --f;
     627                ++l;
     628                ++properties;
     629            }
     630            if (f + l < layoutData->string.length()) {
     631                ++l;
     632            }
     633            qt_getArabicProperties((const unsigned short *)(layoutData->string.unicode()+f), l, props.data());
     634
     635            unsigned short *log_clusters = logClusters(&si);
     636
     637            for (int i = 0; i < len; ++i) {
     638                int gpos = log_clusters[i];
     639                g.attributes[gpos].justification = properties[i].justification;
     640            }
    645641        }
    646642    }
  • trunk/src/gui/text/qtextengine_p.h

    r2 r561  
    22**
    33** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
    4 ** Contact: Qt Software Information (qt-info@nokia.com)
     4** All rights reserved.
     5** Contact: Nokia Corporation (qt-info@nokia.com)
    56**
    67** This file is part of the QtGui module of the Qt Toolkit.
     
    2122** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    2223**
    23 ** In addition, as a special exception, Nokia gives you certain
    24 ** additional rights. These rights are described in the Nokia Qt LGPL
    25 ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
    26 ** package.
     24** In addition, as a special exception, Nokia gives you certain additional
     25** rights.  These rights are described in the Nokia Qt LGPL Exception
     26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
    2727**
    2828** GNU General Public License Usage
     
    3434** met: http://www.gnu.org/copyleft/gpl.html.
    3535**
    36 ** If you are unsure which license is appropriate for your use, please
    37 ** contact the sales department at qt-sales@nokia.com.
     36** If you have questions regarding the use of this file, please contact
     37** Nokia at qt-info@nokia.com.
    3838** $QT_END_LICENSE$
    3939**
     
    111111
    112112    glyph_metrics_t transformed(const QTransform &xform) const;
     113    inline bool isValid() const {return x != 100000 && y != 100000;}
    113114};
    114115Q_DECLARE_TYPEINFO(glyph_metrics_t, Q_PRIMITIVE_TYPE);
     
    345346    inline QScriptItem()
    346347        : position(0),
    347           num_glyphs(0), descent(-1), ascent(-1), width(-1),
     348          num_glyphs(0), descent(-1), ascent(-1), leading(-1), width(-1),
    348349          glyph_data_offset(0) {}
    349350    inline QScriptItem(int p, const QScriptAnalysis &a)
    350351        : position(p), analysis(a),
    351           num_glyphs(0), descent(-1), ascent(-1), width(-1),
     352          num_glyphs(0), descent(-1), ascent(-1), leading(-1), width(-1),
    352353          glyph_data_offset(0) {}
    353354
     
    357358    QFixed descent;
    358359    QFixed ascent;
     360    QFixed leading;
    359361    QFixed width;
    360362    int glyph_data_offset;
     
    373375        : from(0), length(0),
    374376        justified(0), gridfitted(0),
    375         hasTrailingSpaces(0) {}
     377        hasTrailingSpaces(0), leadingIncluded(0) {}
    376378    QFixed descent;
    377379    QFixed ascent;
     380    QFixed leading;
    378381    QFixed x;
    379382    QFixed y;
     
    385388    mutable uint gridfitted : 1;
    386389    uint hasTrailingSpaces : 1;
    387     QFixed height() const { return ascent + descent + 1; }
     390    uint leadingIncluded : 1;
     391    QFixed height() const { return ascent + descent + 1
     392                            + (leadingIncluded?  qMax(QFixed(),leading) : QFixed()); }
     393    QFixed base() const { return ascent
     394                          + (leadingIncluded ? qMax(QFixed(),leading) : QFixed()); }
    388395    void setDefaultHeight(QTextEngine *eng);
    389396    void operator+=(const QScriptLine &other);
     
    394401inline void QScriptLine::operator+=(const QScriptLine &other)
    395402{
     403    leading= qMax(leading + ascent, other.leading + other.ascent) - qMax(ascent, other.ascent);
    396404    descent = qMax(descent, other.descent);
    397405    ascent = qMax(ascent, other.ascent);
     
    476484    }
    477485
    478     QFontEngine *fontEngine(const QScriptItem &si, QFixed *ascent = 0, QFixed *descent = 0) const;
     486    QFontEngine *fontEngine(const QScriptItem &si, QFixed *ascent = 0, QFixed *descent = 0, QFixed *leading = 0) const;
    479487    QFont font(const QScriptItem &si) const;
    480488    inline QFont font() const { return fnt; }
     
    582590    void shapeText(int item) const;
    583591    void shapeTextWithHarfbuzz(int item) const;
    584 #if defined(Q_OS_WINCE)
     592#if defined(Q_WS_WINCE)
    585593    void shapeTextWithCE(int item) const;
    586594#endif
  • trunk/src/gui/text/qtextformat.cpp

    r2 r561  
    22**
    33** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
    4 ** Contact: Qt Software Information (qt-info@nokia.com)
     4** All rights reserved.
     5** Contact: Nokia Corporation (qt-info@nokia.com)
    56**
    67** This file is part of the QtGui module of the Qt Toolkit.
     
    2122** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    2223**
    23 ** In addition, as a special exception, Nokia gives you certain
    24 ** additional rights. These rights are described in the Nokia Qt LGPL
    25 ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
    26 ** package.
     24** In addition, as a special exception, Nokia gives you certain additional
     25** rights.  These rights are described in the Nokia Qt LGPL Exception
     26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
    2727**
    2828** GNU General Public License Usage
     
    3434** met: http://www.gnu.org/copyleft/gpl.html.
    3535**
    36 ** If you are unsure which license is appropriate for your use, please
    37 ** contact the sales department at qt-sales@nokia.com.
     36** If you have questions regarding the use of this file, please contact
     37** Nokia at qt-info@nokia.com.
    3838** $QT_END_LICENSE$
    3939**
     
    5858    used in a QTextDocument.
    5959
    60     \ingroup text
     60    \ingroup richtext-processing
    6161
    6262    When we specify a value for the length of an element in a text document,
     
    9090    \fn Type QTextLength::type() const
    9191
    92     Returns the type of length.
     92    Returns the type of this length object.
    9393
    9494    \sa QTextLength::Type
     
    130130    \enum QTextLength::Type
    131131
    132     \value VariableLength
    133     \value FixedLength
    134     \value PercentageLength
     132    This enum describes the different types a length object can
     133    have.
     134
     135    \value VariableLength The width of the object is variable
     136    \value FixedLength The width of the object is fixed
     137    \value PercentageLength The width of the object is in
     138                            percentage of the maximum width
     139
     140    \sa type()
    135141*/
    136142
     
    143149}
    144150
     151#ifndef QT_NO_DATASTREAM
    145152QDataStream &operator<<(QDataStream &stream, const QTextLength &length)
    146153{
     
    157164    return stream;
    158165}
     166#endif // QT_NO_DATASTREAM
    159167
    160168class QTextFormatPrivate : public QSharedData
     
    258266};
    259267
    260 static uint variantHash(const QVariant &variant)
    261 {
    262     switch (variant.type()) {
     268// this is only safe if sizeof(int) == sizeof(float)
     269static inline uint hash(float d)
     270{
     271    return reinterpret_cast<uint&>(d);
     272}
     273
     274static inline uint hash(const QColor &color)
     275{
     276    return (color.isValid()) ? color.rgba() : 0x234109;
     277}
     278
     279static inline uint hash(const QPen &pen)
     280{
     281    return hash(pen.color()) + hash(pen.widthF());
     282}
     283
     284static inline uint hash(const QBrush &brush)
     285{
     286    return hash(brush.color()) + (brush.style() << 3);
     287}
     288
     289static inline uint variantHash(const QVariant &variant)
     290{
     291    // simple and fast hash functions to differentiate between type and value
     292    switch (variant.userType()) { // sorted by occurrence frequency
     293    case QVariant::String: return qHash(variant.toString());
     294    case QVariant::Double: return hash(variant.toDouble());
     295    case QVariant::Int: return 0x811890 + variant.toInt();
     296    case QVariant::Brush:
     297        return 0x01010101 + hash(qvariant_cast<QBrush>(variant));
     298    case QVariant::Bool: return 0x371818 + variant.toBool();
     299    case QVariant::Pen: return 0x02020202 + hash(qvariant_cast<QPen>(variant));
     300    case QVariant::List:
     301        return 0x8377 + qvariant_cast<QVariantList>(variant).count();
     302    case QVariant::Color: return hash(qvariant_cast<QColor>(variant));
     303      case QVariant::TextLength:
     304        return 0x377 + hash(qvariant_cast<QTextLength>(variant).rawValue());
     305    case QMetaType::Float: return hash(variant.toFloat());
    263306    case QVariant::Invalid: return 0;
    264     case QVariant::Bool: return variant.toBool();
    265     case QVariant::Int: return variant.toInt();
    266     case QVariant::Double: return static_cast<int>(variant.toDouble());
    267     case QVariant::String: return qHash(variant.toString());
    268     case QVariant::Color: return qHash(qvariant_cast<QColor>(variant).rgb());
    269307    default: break;
    270308    }
    271309    return qHash(variant.typeName());
     310}
     311
     312static inline int getHash(const QTextFormatPrivate *d, int format)
     313{
     314    return (d ? d->hash() : 0) + format;
    272315}
    273316
     
    318361                break;
    319362            case QTextFormat::FontPointSize:
    320                 f.setPointSizeF(props.at(i).value.toDouble());
     363                f.setPointSizeF(props.at(i).value.toReal());
    321364                break;
    322365            case  QTextFormat::FontPixelSize:
     
    345388                break;
    346389            case QTextFormat::FontLetterSpacing:
    347                 f.setLetterSpacing(QFont::PercentageSpacing, props.at(i).value.toDouble());
     390                f.setLetterSpacing(QFont::PercentageSpacing, props.at(i).value.toReal());
    348391                break;
    349392            case QTextFormat::FontWordSpacing:
    350                 f.setWordSpacing(props.at(i).value.toDouble());
     393                f.setWordSpacing(props.at(i).value.toReal());
    351394                break;
    352395            case QTextFormat::FontCapitalization:
     
    375418}
    376419
     420#ifndef QT_NO_DATASTREAM
    377421Q_GUI_EXPORT QDataStream &operator<<(QDataStream &stream, const QTextFormat &fmt)
    378422{
     
    397441    return stream;
    398442}
     443#endif // QT_NO_DATASTREAM
    399444
    400445/*!
     
    405450    QTextDocument.
    406451
    407     \ingroup text
     452    \ingroup richtext-processing
    408453    \ingroup shared
    409454
     
    414459    specific parts of the document.
    415460
    416     A format has a \c FormatType which specifies the kinds of thing it
     461    A format has a \c FormatType which specifies the kinds of text item it
    417462    can format; e.g. a block of text, a list, a table, etc. A format
    418463    also has various properties (some specific to particular format
     
    438483    lists, frames, and tables inside the document.
    439484
    440     \sa {Text Processing Classes}
     485    \sa {Rich Text Processing}
    441486*/
    442487
     
    444489    \enum QTextFormat::FormatType
    445490
    446     \value InvalidFormat
    447     \value BlockFormat
    448     \value CharFormat
    449     \value ListFormat
    450     \value TableFormat
    451     \value FrameFormat
     491    This enum describes the text item a QTextFormat object is formatting.
     492
     493    \value InvalidFormat An invalid format as created by the default
     494                         constructor
     495    \value BlockFormat The object formats a text block
     496    \value CharFormat The object formats a single character
     497    \value ListFormat The object formats a list
     498    \value TableFormat The object formats a table
     499    \value FrameFormat The object formats a frame
    452500
    453501    \value UserFormat
     502
     503    \sa QTextCharFormat, QTextBlockFormat, QTextListFormat,
     504    QTextTableFormat, type()
    454505*/
    455506
     
    457508    \enum QTextFormat::Property
    458509
    459     \value ObjectIndex
     510    This enum describes the different properties a format can have.
     511
     512    \value ObjectIndex The index of the formatted object. See objectIndex().
    460513
    461514    Paragraph and character properties
    462515
    463     \value CssFloat
     516    \value CssFloat How a frame is located relative to the surrounding text
    464517    \value LayoutDirection  The layout direction of the text in the document
    465518                            (Qt::LayoutDirection).
     
    479532    \value TextIndent
    480533    \value TabPositions     Specifies the tab positions.  The tab positions are structs of QTextOption::Tab which are stored in
    481                                           a QList (internally, in a QList<QVariant>).
     534                            a QList (internally, in a QList<QVariant>).
    482535    \value BlockIndent
    483536    \value BlockNonBreakableLines
    484     \value BlockTrailingHorizontalRulerWidth
     537    \value BlockTrailingHorizontalRulerWidth The width of a horizontal ruler element.
    485538
    486539    Character properties
     
    488541    \value FontFamily
    489542    \value FontPointSize
     543    \value FontPixelSize
    490544    \value FontSizeAdjustment       Specifies the change in size given to the fontsize already set using
    491545                                    FontPointSize or FontPixelSize.
     546    \value FontFixedPitch
    492547    \omitvalue FontSizeIncrement
    493548    \value FontWeight
     
    496551    \value FontOverline
    497552    \value FontStrikeOut
    498     \value FontFixedPitch
    499     \value FontPixelSize
    500553    \value FontCapitalization Specifies the capitalization type that is to be applied to the text.
    501554    \value FontLetterSpacing Changes the default spacing between individual letters in the font. The value is
     
    509562    \omitvalue FirstFontProperty
    510563    \omitvalue LastFontProperty
    511    
     564
    512565    \value TextUnderlineColor
    513566    \value TextVerticalAlignment
     
    530583    \value FrameBorder
    531584    \value FrameBorderBrush
    532     \value FrameBorderStyle
     585    \value FrameBorderStyle See the \l{QTextFrameFormat::BorderStyle}{BorderStyle} enum.
    533586    \value FrameBottomMargin
    534587    \value FrameHeight
     
    562615    Selection properties
    563616
    564     \value FullWidthSelection When set on the characterFormat of a selection, the whole width of the text will be shown selected
     617    \value FullWidthSelection When set on the characterFormat of a selection,
     618                              the whole width of the text will be shown selected.
    565619
    566620    Page break properties
    567621
    568     \value PageBreakPolicy
     622    \value PageBreakPolicy Specifies how pages are broken. See the PageBreakFlag enum.
    569623
    570624    \value UserProperty
     625
     626    \sa property(), setProperty()
    571627*/
    572628
    573629/*!
    574630    \enum QTextFormat::ObjectTypes
     631
     632    This enum describes what kind of QTextObject this format is associated with.
    575633
    576634    \value NoObject
     
    579637    \value TableCellObject
    580638    \value UserObject The first object that can be used for application-specific purposes.
     639
     640    \sa QTextObject, QTextTable, QTextObject::format()
    581641*/
    582642
     
    584644    \enum QTextFormat::PageBreakFlag
    585645    \since 4.2
     646
     647    This enum describes how page breaking is performed when printing. It maps to the
     648    corresponding css properties.
    586649
    587650    \value PageBreak_Auto The page break is determined automatically depending on the
     
    589652    \value PageBreak_AlwaysBefore The page is always broken before the paragraph/table
    590653    \value PageBreak_AlwaysAfter  A new page is always started after the paragraph/table
     654
     655    \sa QTextBlockFormat::pageBreakPolicy(), QTextFrameFormat::pageBreakPolicy(),
     656    PageBreakPolicy
    591657*/
    592658
     
    822888        return false;
    823889    const QVariant prop = d->property(propertyId);
    824     if (prop.type() != QVariant::Bool)
     890    if (prop.userType() != QVariant::Bool)
    825891        return false;
    826892    return prop.toBool();
     
    838904        return 0;
    839905    const QVariant prop = d->property(propertyId);
    840     if (prop.type() != QVariant::Int)
     906    if (prop.userType() != QVariant::Int)
    841907        return 0;
    842908    return prop.toInt();
     
    845911/*!
    846912    Returns the value of the property specified by \a propertyId. If the
    847     property isn't of QVariant::Double type, 0 is returned instead.
     913    property isn't of QVariant::Double or QMetaType::Float type, 0 is
     914    returned instead.
    848915
    849916    \sa setProperty() boolProperty() intProperty() stringProperty() colorProperty() lengthProperty() lengthVectorProperty() Property
     
    854921        return 0.;
    855922    const QVariant prop = d->property(propertyId);
    856     if (prop.type() != QVariant::Double)
     923    if (prop.userType() != QVariant::Double && prop.userType() != QMetaType::Float)
    857924        return 0.;
    858     return prop.toDouble(); // ####
     925    return qVariantValue<qreal>(prop);
    859926}
    860927
     
    871938        return QString();
    872939    const QVariant prop = d->property(propertyId);
    873     if (prop.type() != QVariant::String)
     940    if (prop.userType() != QVariant::String)
    874941        return QString();
    875942    return prop.toString();
     
    889956        return QColor();
    890957    const QVariant prop = d->property(propertyId);
    891     if (prop.type() != QVariant::Color)
     958    if (prop.userType() != QVariant::Color)
    892959        return QColor();
    893960    return qvariant_cast<QColor>(prop);
     
    906973        return QPen(Qt::NoPen);
    907974    const QVariant prop = d->property(propertyId);
    908     if (prop.type() != QVariant::Pen)
     975    if (prop.userType() != QVariant::Pen)
    909976        return QPen(Qt::NoPen);
    910977    return qvariant_cast<QPen>(prop);
     
    923990        return QBrush(Qt::NoBrush);
    924991    const QVariant prop = d->property(propertyId);
    925     if (prop.type() != QVariant::Brush)
     992    if (prop.userType() != QVariant::Brush)
    926993        return QBrush(Qt::NoBrush);
    927994    return qvariant_cast<QBrush>(prop);
     
    9531020        return vector;
    9541021    const QVariant prop = d->property(propertyId);
    955     if (prop.type() != QVariant::List)
     1022    if (prop.userType() != QVariant::List)
    9561023        return vector;
    9571024
     
    9591026    for (int i=0; i<propertyList.size(); ++i) {
    9601027        QVariant var = propertyList.at(i);
    961         if (var.type() == QVariant::TextLength)
     1028        if (var.userType() == QVariant::TextLength)
    9621029            vector.append(qvariant_cast<QTextLength>(var));
    9631030    }
     
    9681035/*!
    9691036    Returns the property specified by the given \a propertyId.
     1037
     1038    \sa Property
    9701039*/
    9711040QVariant QTextFormat::property(int propertyId) const
     
    9761045/*!
    9771046    Sets the property specified by the \a propertyId to the given \a value.
     1047
     1048    \sa Property
    9781049*/
    9791050void QTextFormat::setProperty(int propertyId, const QVariant &value)
     
    10031074
    10041075/*!
    1005   Clears the value of the property given by \a propertyId
    1006  */
     1076    Clears the value of the property given by \a propertyId
     1077
     1078    \sa Property
     1079*/
    10071080void QTextFormat::clearProperty(int propertyId)
    10081081{
     
    10161089    \fn void QTextFormat::setObjectType(int type)
    10171090
    1018     Sets the text format's object \a type. See \c{ObjectTypes}.
     1091    Sets the text format's object type to \a type.
     1092
     1093    \sa ObjectTypes, objectType()
    10191094*/
    10201095
     
    10231098    \fn int QTextFormat::objectType() const
    10241099
    1025     Returns the text format's object type. See \c{ObjectTypes}.
     1100    Returns the text format's object type.
     1101
     1102    \sa ObjectTypes, setObjectType()
    10261103*/
    10271104
     
    10371114        return -1;
    10381115    const QVariant prop = d->property(ObjectIndex);
    1039     if (prop.type() != QVariant::Int) // ####
     1116    if (prop.userType() != QVariant::Int) // ####
    10401117        return -1;
    10411118    return prop.toInt();
     
    11421219    characters in a QTextDocument.
    11431220
    1144     \ingroup text
     1221    \ingroup richtext-processing
    11451222
    11461223    The character format of text in a document specifies the visual properties
     
    14501527    \since 4.5
    14511528    \fn  bool QTextCharFormat::fontKerning() const
    1452     Returns true if the the font kerning is enabled.
     1529    Returns true if the font kerning is enabled.
    14531530
    14541531    \sa setFontKerning()
     
    15631640
    15641641    Sets the hypertext link for the text format to the given \a value.
    1565     This is typically a URL like "http://qtsoftware.com/index.html".
     1642    This is typically a URL like "http://example.com/index.html".
    15661643
    15671644    The anchor will be displayed with the \a value as its display text;
     
    16131690{
    16141691    QVariant prop = property(AnchorName);
    1615     if (prop.type() == QVariant::StringList)
     1692    if (prop.userType() == QVariant::StringList)
    16161693        return prop.toStringList().value(0);
    1617     else if (prop.type() != QVariant::String)
     1694    else if (prop.userType() != QVariant::String)
    16181695        return QString();
    16191696    return prop.toString();
     
    16311708{
    16321709    QVariant prop = property(AnchorName);
    1633     if (prop.type() == QVariant::StringList)
     1710    if (prop.userType() == QVariant::StringList)
    16341711        return prop.toStringList();
    1635     else if (prop.type() != QVariant::String)
     1712    else if (prop.userType() != QVariant::String)
    16361713        return QStringList();
    16371714    return QStringList(prop.toString());
     
    17551832    blocks of text in a QTextDocument.
    17561833
    1757     \ingroup text
     1834    \ingroup richtext-processing
    17581835
    17591836    A document is composed of a list of blocks, represented by QTextBlock
     
    20462123    lists in a QTextDocument.
    20472124
    2048     \ingroup text
     2125    \ingroup richtext-processing
    20492126
    20502127    A list is composed of one or more items, represented as text blocks.
     
    20752152    \value ListLowerAlpha  lower case Latin characters in alphabetical order
    20762153    \value ListUpperAlpha  upper case Latin characters in alphabetical order
     2154    \value ListLowerRoman  lower case roman numerals (supports up to 4999 items only)
     2155    \value ListUpperRoman  upper case roman numerals (supports up to 4999 items only)
    20772156    \omitvalue ListStyleUndefined
    20782157*/
     
    21112190    \fn void QTextListFormat::setStyle(Style style)
    21122191
    2113     Sets the list format's \a style. See \c{Style} for the available styles.
    2114 
    2115     \sa style()
     2192    Sets the list format's \a style.
     2193
     2194    \sa style() Style
    21162195*/
    21172196
     
    21192198    \fn Style QTextListFormat::style() const
    21202199
    2121     Returns the list format's style. See \c{Style}.
    2122 
    2123     \sa setStyle()
     2200    Returns the list format's style.
     2201
     2202    \sa setStyle() Style
    21242203*/
    21252204
     
    21542233    frames in a QTextDocument.
    21552234
    2156     \ingroup text
     2235    \ingroup richtext-processing
    21572236
    21582237    A text frame groups together one or more blocks of text, providing a layer
     
    21832262    \enum QTextFrameFormat::Position
    21842263
     2264    This enum describes how a frame is located relative to the surrounding text.
     2265
    21852266    \value InFlow
    21862267    \value FloatLeft
    21872268    \value FloatRight
    21882269
     2270    \sa position() CssFloat
    21892271*/
    21902272
     
    21922274    \enum QTextFrameFormat::BorderStyle
    21932275    \since 4.3
     2276
     2277    This enum describes different border styles for the text frame.
    21942278
    21952279    \value BorderStyle_None
     
    22052289    \value BorderStyle_Outset
    22062290
     2291    \sa borderStyle() FrameBorderStyle
    22072292*/
    22082293
     
    24742559    tables in a QTextDocument.
    24752560
    2476     \ingroup text
     2561    \ingroup richtext-processing
    24772562
    24782563    A table is a group of cells ordered into rows and columns. Each table
     
    26802765    images in a QTextDocument.
    26812766
    2682     \ingroup text
     2767    \ingroup richtext-processing
    26832768
    26842769    Inline images are represented by an object replacement character
     
    29493034    table cells in a QTextDocument.
    29503035
    2951     \ingroup text
     3036    \ingroup richtext-processing
    29523037
    29533038    The table cell format of a table cell in a document specifies the visual
     
    29833068int QTextFormatCollection::indexForFormat(const QTextFormat &format)
    29843069{
    2985     uint hash = format.d ? format.d->hash() : 0;
    2986     if (hashes.contains(hash)) {
    2987         for (int i = 0; i < formats.size(); ++i) {
    2988             if (formats.at(i) == format)
    2989                 return i;
     3070    uint hash = getHash(format.d, format.format_type);
     3071    QMultiHash<uint, int>::const_iterator i = hashes.find(hash);
     3072    while (i != hashes.end() && i.key() == hash) {
     3073        if (formats.value(i.value()) == format) {
     3074            return i.value();
    29903075        }
     3076        ++i;
    29913077    }
     3078
    29923079    int idx = formats.size();
    29933080    formats.append(format);
    29943081
    2995     QTextFormat &f = formats.last();
    2996     if (!f.d)
    2997         f.d = new QTextFormatPrivate;
    2998     f.d->resolveFont(defaultFnt);
    2999 
    3000     hashes.insert(hash);
     3082    QT_TRY{
     3083        QTextFormat &f = formats.last();
     3084        if (!f.d)
     3085            f.d = new QTextFormatPrivate;
     3086        f.d->resolveFont(defaultFnt);
     3087
     3088        hashes.insert(hash, idx);
     3089
     3090    } QT_CATCH(...) {
     3091        formats.pop_back();
     3092        QT_RETHROW;
     3093    }
    30013094    return idx;
    30023095}
     
    30043097bool QTextFormatCollection::hasFormatCached(const QTextFormat &format) const
    30053098{
    3006     uint hash = format.d ? format.d->hash() : 0;
    3007     if (hashes.contains(hash)) {
    3008         for (int i = 0; i < formats.size(); ++i)
    3009             if (formats.at(i) == format)
    3010                 return true;
     3099    uint hash = getHash(format.d, format.format_type);
     3100    QMultiHash<uint, int>::const_iterator i = hashes.find(hash);
     3101    while (i != hashes.end() && i.key() == hash) {
     3102        if (formats.value(i.value()) == format) {
     3103            return true;
     3104        }
     3105        ++i;
    30113106    }
    30123107    return false;
  • trunk/src/gui/text/qtextformat.h

    r2 r561  
    22**
    33** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
    4 ** Contact: Qt Software Information (qt-info@nokia.com)
     4** All rights reserved.
     5** Contact: Nokia Corporation (qt-info@nokia.com)
    56**
    67** This file is part of the QtGui module of the Qt Toolkit.
     
    2122** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    2223**
    23 ** In addition, as a special exception, Nokia gives you certain
    24 ** additional rights. These rights are described in the Nokia Qt LGPL
    25 ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
    26 ** package.
     24** In addition, as a special exception, Nokia gives you certain additional
     25** rights.  These rights are described in the Nokia Qt LGPL Exception
     26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
    2727**
    2828** GNU General Public License Usage
     
    3434** met: http://www.gnu.org/copyleft/gpl.html.
    3535**
    36 ** If you are unsure which license is appropriate for your use, please
    37 ** contact the sales department at qt-sales@nokia.com.
     36** If you have questions regarding the use of this file, please contact
     37** Nokia at qt-info@nokia.com.
    3838** $QT_END_LICENSE$
    3939**
     
    7777class QTextLength;
    7878
     79#ifndef QT_NO_DATASTREAM
    7980Q_GUI_EXPORT QDataStream &operator<<(QDataStream &, const QTextLength &);
    8081Q_GUI_EXPORT QDataStream &operator>>(QDataStream &, QTextLength &);
     82#endif
    8183
    8284class Q_GUI_EXPORT QTextLength
     
    120122    : lengthType(atype), fixedValueOrPercentage(avalue) {}
    121123
     124#ifndef QT_NO_DATASTREAM
    122125Q_GUI_EXPORT QDataStream &operator<<(QDataStream &, const QTextFormat &);
    123126Q_GUI_EXPORT QDataStream &operator>>(QDataStream &, QTextFormat &);
     127#endif
    124128
    125129class Q_GUI_EXPORT QTextFormat
     
    233237        ImageHeight = 0x5011,
    234238
     239        // internal
     240        /*
     241           SuppressText = 0x5012,
     242           SuppressBackground = 0x513
     243        */
     244
    235245        // selection properties
    236246        FullWidthSelection = 0x06000,
     
    595605        ListLowerAlpha = -5,
    596606        ListUpperAlpha = -6,
     607        ListLowerRoman = -7,
     608        ListUpperRoman = -8,
    597609        ListStyleUndefined = 0
    598610    };
  • trunk/src/gui/text/qtextformat_p.h

    r2 r561  
    22**
    33** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
    4 ** Contact: Qt Software Information (qt-info@nokia.com)
     4** All rights reserved.
     5** Contact: Nokia Corporation (qt-info@nokia.com)
    56**
    67** This file is part of the QtGui module of the Qt Toolkit.
     
    2122** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    2223**
    23 ** In addition, as a special exception, Nokia gives you certain
    24 ** additional rights. These rights are described in the Nokia Qt LGPL
    25 ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
    26 ** package.
     24** In addition, as a special exception, Nokia gives you certain additional
     25** rights.  These rights are described in the Nokia Qt LGPL Exception
     26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
    2727**
    2828** GNU General Public License Usage
     
    3434** met: http://www.gnu.org/copyleft/gpl.html.
    3535**
    36 ** If you are unsure which license is appropriate for your use, please
    37 ** contact the sales department at qt-sales@nokia.com.
     36** If you have questions regarding the use of this file, please contact
     37** Nokia at qt-info@nokia.com.
    3838** $QT_END_LICENSE$
    3939**
     
    5656#include "QtGui/qtextformat.h"
    5757#include "QtCore/qvector.h"
    58 #include "QtCore/qset.h"
     58#include "QtCore/qhash.h"
    5959
    6060QT_BEGIN_NAMESPACE
     
    9898    FormatVector formats;
    9999    QVector<qint32> objFormats;
    100     QSet<uint> hashes;
     100    QMultiHash<uint,int> hashes;
    101101
    102102    inline QFont defaultFont() const { return defaultFnt; }
  • trunk/src/gui/text/qtexthtmlparser.cpp

    r2 r561  
    22**
    33** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
    4 ** Contact: Qt Software Information (qt-info@nokia.com)
     4** All rights reserved.
     5** Contact: Nokia Corporation (qt-info@nokia.com)
    56**
    67** This file is part of the QtGui module of the Qt Toolkit.
     
    2122** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    2223**
    23 ** In addition, as a special exception, Nokia gives you certain
    24 ** additional rights. These rights are described in the Nokia Qt LGPL
    25 ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
    26 ** package.
     24** In addition, as a special exception, Nokia gives you certain additional
     25** rights.  These rights are described in the Nokia Qt LGPL Exception
     26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
    2727**
    2828** GNU General Public License Usage
     
    3434** met: http://www.gnu.org/copyleft/gpl.html.
    3535**
    36 ** If you are unsure which license is appropriate for your use, please
    37 ** contact the sales department at qt-sales@nokia.com.
     36** If you have questions regarding the use of this file, please contact
     37** Nokia at qt-info@nokia.com.
    3838** $QT_END_LICENSE$
    3939**
     
    344344}
    345345
    346 static const uint windowsLatin1ExtendedCharacters[0xA0 - 0x80] = {
     346static const ushort windowsLatin1ExtendedCharacters[0xA0 - 0x80] = {
    347347    0x20ac, // 0x80
    348348    0x0081, // 0x81 direct mapping
     
    500500    for (int i = 0; i < count(); ++i) {
    501501        qDebug().nospace() << qPrintable(QString(depth(i)*4, QLatin1Char(' ')))
    502                            << qPrintable(at(i).tag) << ":"
     502                           << qPrintable(at(i).tag) << ':'
    503503                           << quoteNewline(at(i).text);
    504504            ;
     
    12071207                case QCss::Value_LowerAlpha: hasOwnListStyle = true; listStyle = QTextListFormat::ListLowerAlpha; break;
    12081208                case QCss::Value_UpperAlpha: hasOwnListStyle = true; listStyle = QTextListFormat::ListUpperAlpha; break;
     1209                case QCss::Value_LowerRoman: hasOwnListStyle = true; listStyle = QTextListFormat::ListLowerRoman; break;
     1210                case QCss::Value_UpperRoman: hasOwnListStyle = true; listStyle = QTextListFormat::ListUpperRoman; break;
    12091211                default: break;
    12101212            }
     
    14421444static void setWidthAttribute(QTextLength *width, QString value)
    14431445{
    1444     qreal realVal;
    14451446    bool ok = false;
    1446     realVal = value.toDouble(&ok);
     1447    qreal realVal = value.toDouble(&ok);
    14471448    if (ok) {
    14481449        *width = QTextLength(QTextLength::FixedLength, realVal);
    14491450    } else {
    14501451        value = value.trimmed();
    1451         if (!value.isEmpty() && value.at(value.length() - 1) == QLatin1Char('%')) {
     1452        if (!value.isEmpty() && value.endsWith(QLatin1Char('%'))) {
    14521453            value.chop(1);
    14531454            realVal = value.toDouble(&ok);
     
    15411542                    } else if (value == QLatin1String("A")) {
    15421543                        node->listStyle = QTextListFormat::ListUpperAlpha;
     1544                    } else if (value == QLatin1String("i")) {
     1545                        node->listStyle = QTextListFormat::ListLowerRoman;
     1546                    } else if (value == QLatin1String("I")) {
     1547                        node->listStyle = QTextListFormat::ListUpperRoman;
    15431548                    } else {
    15441549                        value = value.toLower();
  • trunk/src/gui/text/qtexthtmlparser_p.h

    r2 r561  
    22**
    33** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
    4 ** Contact: Qt Software Information (qt-info@nokia.com)
     4** All rights reserved.
     5** Contact: Nokia Corporation (qt-info@nokia.com)
    56**
    67** This file is part of the QtGui module of the Qt Toolkit.
     
    2122** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    2223**
    23 ** In addition, as a special exception, Nokia gives you certain
    24 ** additional rights. These rights are described in the Nokia Qt LGPL
    25 ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
    26 ** package.
     24** In addition, as a special exception, Nokia gives you certain additional
     25** rights.  These rights are described in the Nokia Qt LGPL Exception
     26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
    2727**
    2828** GNU General Public License Usage
     
    3434** met: http://www.gnu.org/copyleft/gpl.html.
    3535**
    36 ** If you are unsure which license is appropriate for your use, please
    37 ** contact the sales department at qt-sales@nokia.com.
     36** If you have questions regarding the use of this file, please contact
     37** Nokia at qt-info@nokia.com.
    3838** $QT_END_LICENSE$
    3939**
  • trunk/src/gui/text/qtextimagehandler.cpp

    r2 r561  
    22**
    33** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
    4 ** Contact: Qt Software Information (qt-info@nokia.com)
     4** All rights reserved.
     5** Contact: Nokia Corporation (qt-info@nokia.com)
    56**
    67** This file is part of the QtGui module of the Qt Toolkit.
     
    2122** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    2223**
    23 ** In addition, as a special exception, Nokia gives you certain
    24 ** additional rights. These rights are described in the Nokia Qt LGPL
    25 ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
    26 ** package.
     24** In addition, as a special exception, Nokia gives you certain additional
     25** rights.  These rights are described in the Nokia Qt LGPL Exception
     26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
    2727**
    2828** GNU General Public License Usage
     
    3434** met: http://www.gnu.org/copyleft/gpl.html.
    3535**
    36 ** If you are unsure which license is appropriate for your use, please
    37 ** contact the sales department at qt-sales@nokia.com.
     36** If you have questions regarding the use of this file, please contact
     37** Nokia at qt-info@nokia.com.
    3838** $QT_END_LICENSE$
    3939**
  • trunk/src/gui/text/qtextimagehandler_p.h

    r2 r561  
    22**
    33** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
    4 ** Contact: Qt Software Information (qt-info@nokia.com)
     4** All rights reserved.
     5** Contact: Nokia Corporation (qt-info@nokia.com)
    56**
    67** This file is part of the QtGui module of the Qt Toolkit.
     
    2122** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    2223**
    23 ** In addition, as a special exception, Nokia gives you certain
    24 ** additional rights. These rights are described in the Nokia Qt LGPL
    25 ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
    26 ** package.
     24** In addition, as a special exception, Nokia gives you certain additional
     25** rights.  These rights are described in the Nokia Qt LGPL Exception
     26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
    2727**
    2828** GNU General Public License Usage
     
    3434** met: http://www.gnu.org/copyleft/gpl.html.
    3535**
    36 ** If you are unsure which license is appropriate for your use, please
    37 ** contact the sales department at qt-sales@nokia.com.
     36** If you have questions regarding the use of this file, please contact
     37** Nokia at qt-info@nokia.com.
    3838** $QT_END_LICENSE$
    3939**
     
    6161class QTextImageFormat;
    6262
    63 class Q_GUI_EXPORT QTextImageHandler : public QObject,
     63class QTextImageHandler : public QObject,
    6464                          public QTextObjectInterface
    6565{
     
    7373
    7474    typedef QImage (*ExternalImageLoaderFunction)(const QString &name, const QString &context);
    75     static ExternalImageLoaderFunction externalLoader;
     75    static Q_GUI_EXPORT ExternalImageLoaderFunction externalLoader; //this is needed by Qt3Support
    7676};
    7777
  • trunk/src/gui/text/qtextlayout.cpp

    r2 r561  
    22**
    33** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
    4 ** Contact: Qt Software Information (qt-info@nokia.com)
     4** All rights reserved.
     5** Contact: Nokia Corporation (qt-info@nokia.com)
    56**
    67** This file is part of the QtGui module of the Qt Toolkit.
     
    2122** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    2223**
    23 ** In addition, as a special exception, Nokia gives you certain
    24 ** additional rights. These rights are described in the Nokia Qt LGPL
    25 ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
    26 ** package.
     24** In addition, as a special exception, Nokia gives you certain additional
     25** rights.  These rights are described in the Nokia Qt LGPL Exception
     26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
    2727**
    2828** GNU General Public License Usage
     
    3434** met: http://www.gnu.org/copyleft/gpl.html.
    3535**
    36 ** If you are unsure which license is appropriate for your use, please
    37 ** contact the sales department at qt-sales@nokia.com.
     36** If you have questions regarding the use of this file, please contact
     37** Nokia at qt-info@nokia.com.
    3838** $QT_END_LICENSE$
    3939**
     
    6262
    6363#define ObjectSelectionBrush (QTextFormat::ForegroundBrush + 1)
     64#define SuppressText 0x5012
     65#define SuppressBackground 0x513
    6466
    6567static inline QFixed leadingSpaceWidth(QTextEngine *eng, const QScriptLine &line)
     
    127129    a QTextLayout.
    128130
    129     \ingroup text
     131    \ingroup richtext-processing
    130132
    131133    This class is only used if the text layout is used to lay out
     
    284286    paragraph of text.
    285287
    286     \ingroup text
     288    \ingroup richtext-processing
    287289
    288290    It offers most features expected from a modern text layout
     
    366368    if (paintdevice)
    367369        f = QFont(font, paintdevice);
    368     d = new QTextEngine((text.isNull() ? (const QString&)QString::fromLatin1("") : text), f.d);
     370    d = new QTextEngine((text.isNull() ? (const QString&)QString::fromLatin1("") : text), f.d.data());
    369371}
    370372
     
    859861        xmax = qMax(xmax, si.x+qMax(si.width, si.textWidth));
    860862        // ### shouldn't the ascent be used in ymin???
    861         ymax = qMax(ymax, si.y+si.ascent+si.descent+1);
     863        ymax = qMax(ymax, si.y+si.height());
    862864    }
    863865    return QRectF(xmin.toReal(), ymin.toReal(), (xmax-xmin).toReal(), (ymax-ymin).toReal());
     
    10701072    QTextLineItemIterator iterator(eng, lineNumber, pos, selection);
    10711073
    1072     const QFixed y = QFixed::fromReal(pos.y()) + line.y + line.ascent;
    1073 
     1074
     1075
     1076    const qreal selectionY = pos.y() + line.y.toReal();
    10741077    const qreal lineHeight = line.height().toReal();
    1075     const qreal selectionY = (y - line.ascent).toReal();
    10761078
    10771079    QFixed lastSelectionX = iterator.x;
     
    11441146
    11451147    QPainterPath excludedRegion;
     1148    QPainterPath textDoneRegion;
    11461149    for (int i = 0; i < selections.size(); ++i) {
    11471150        FormatRange selection = selections.at(i);
     
    12031206
    12041207
     1208
     1209        bool hasText = (selection.format.foreground().style() != Qt::NoBrush);
     1210        bool hasBackground= (selection.format.background().style() != Qt::NoBrush);
     1211       
     1212        if (hasBackground) {
     1213            selection.format.setProperty(ObjectSelectionBrush, selection.format.property(QTextFormat::BackgroundBrush));
     1214            // don't just clear the property, set an empty brush that overrides a potential
     1215            // background brush specified in the text
     1216            selection.format.setProperty(QTextFormat::BackgroundBrush, QBrush());
     1217            selection.format.clearProperty(QTextFormat::OutlinePen);
     1218        }
     1219
     1220        selection.format.setProperty(SuppressText, !hasText);
     1221
     1222        if (hasText && !hasBackground && !(textDoneRegion & region).isEmpty())
     1223            continue;
     1224
    12051225        p->save();
    12061226        p->setClipPath(region, Qt::IntersectClip);
    1207 
    1208         selection.format.setProperty(ObjectSelectionBrush, selection.format.property(QTextFormat::BackgroundBrush));
    1209         // don't just clear the property, set an empty brush that overrides a potential
    1210         // background brush specified in the text
    1211         selection.format.setProperty(QTextFormat::BackgroundBrush, QBrush());
    1212         selection.format.clearProperty(QTextFormat::OutlinePen);
    12131227
    12141228        for (int line = firstLine; line < lastLine; ++line) {
     
    12181232        p->restore();
    12191233
    1220         if (selection.format.foreground().style() != Qt::NoBrush) // i.e. we have drawn text
    1221             excludedRegion += region;
     1234        if (hasText) {
     1235            textDoneRegion += region;
     1236        } else {
     1237            if (hasBackground)
     1238                textDoneRegion -= region;
     1239        }
     1240
     1241        excludedRegion += region;
     1242    }
     1243
     1244    QPainterPath needsTextButNoBackground = excludedRegion - textDoneRegion;
     1245    if (!needsTextButNoBackground.isEmpty()){
     1246        p->save();
     1247        p->setClipPath(needsTextButNoBackground, Qt::IntersectClip);
     1248        FormatRange selection;
     1249        selection.start = 0;
     1250        selection.length = INT_MAX;
     1251        selection.format.setProperty(SuppressBackground, true);
     1252        for (int line = firstLine; line < lastLine; ++line) {
     1253            QTextLine l(line, d);
     1254            l.draw(p, position, &selection);
     1255        }
     1256        p->restore();
    12221257    }
    12231258
     
    13001335
    13011336    int itm = d->findItem(cursorPosition - 1);
    1302     QFixed ascent = sl.ascent;
     1337    QFixed base = sl.base();
    13031338    QFixed descent = sl.descent;
    13041339    bool rightToLeft = (d->option.textDirection() == Qt::RightToLeft);
     
    13061341        const QScriptItem &si = d->layoutData->items.at(itm);
    13071342        if (si.ascent > 0)
    1308             ascent = si.ascent;
     1343            base = si.ascent;
    13091344        if (si.descent > 0)
    13101345            descent = si.descent;
    13111346        rightToLeft = si.analysis.bidiLevel % 2;
    13121347    }
    1313     qreal y = position.y() + (sl.y + sl.ascent - ascent).toReal();
     1348    qreal y = position.y() + (sl.y + sl.base() - base).toReal();
    13141349    bool toggleAntialiasing = !(p->renderHints() & QPainter::Antialiasing)
    13151350                              && (p->transform().type() > QTransform::TxTranslate);
    13161351    if (toggleAntialiasing)
    13171352        p->setRenderHint(QPainter::Antialiasing);
    1318     p->fillRect(QRectF(x, y, qreal(width), (ascent + descent).toReal()), p->pen().brush());
     1353    p->fillRect(QRectF(x, y, qreal(width), (base + descent + 1).toReal()), p->pen().brush());
    13191354    if (toggleAntialiasing)
    13201355        p->setRenderHint(QPainter::Antialiasing, false);
     
    13341369    \brief The QTextLine class represents a line of text inside a QTextLayout.
    13351370
    1336     \ingroup text
     1371    \ingroup richtext-processing
    13371372
    13381373    A text line is usually created by QTextLayout::createLine().
     
    14661501
    14671502/*!
    1468     Returns the line's height. This is equal to ascent() + descent() + 1.
    1469 
    1470     \sa ascent() descent()
     1503    Returns the line's height. This is equal to ascent() + descent() + 1
     1504    if leading is not included. If leading is included, this equals to
     1505    ascent() + descent() + leading() + 1.
     1506
     1507    \sa ascent() descent() leading() setLeadingIncluded()
    14711508*/
    14721509qreal QTextLine::height() const
     
    14741511    return eng->lines[i].height().toReal();
    14751512}
     1513
     1514/*!
     1515    \since 4.6
     1516
     1517    Returns the line's leading.
     1518
     1519    \sa ascent() descent() height()
     1520*/
     1521qreal QTextLine::leading() const
     1522{
     1523    return eng->lines[i].leading.toReal();
     1524}
     1525
     1526/*! \since 4.6
     1527
     1528  Includes positive leading into the line's height if \a included is true;
     1529  otherwise does not include leading.
     1530
     1531  By default, leading is not included.
     1532
     1533  Note that negative leading is ignored, it must be handled
     1534  in the code using the text lines by letting the lines overlap.
     1535
     1536  \sa leadingIncluded()
     1537
     1538*/
     1539void QTextLine::setLeadingIncluded(bool included)
     1540{
     1541    eng->lines[i].leadingIncluded= included;
     1542
     1543}
     1544
     1545/*! \since 4.6
     1546
     1547  Returns true if positive leading is included into the line's height; otherwise returns false.
     1548
     1549  By default, leading is not included.
     1550
     1551  \sa setLeadingIncluded()
     1552*/
     1553bool QTextLine::leadingIncluded() const
     1554{
     1555    return eng->lines[i].leadingIncluded;
     1556}
     1557
    14761558
    14771559/*!
     
    15551637#endif
    15561638
    1557 static inline bool checkFullOtherwiseExtend(QScriptLine &line, QScriptLine &tmpData, QScriptLine &spaceData,
    1558                                             int glyphCount, int maxGlyphs, QFixed &minw, bool manualWrap,
    1559                                             QFixed softHyphenWidth = QFixed())
    1560 {
     1639namespace {
     1640
     1641    struct LineBreakHelper
     1642    {
     1643        LineBreakHelper() : glyphCount(0), maxGlyphs(0), manualWrap(false) {}
     1644
     1645        QScriptLine tmpData;
     1646        QScriptLine spaceData;
     1647
     1648        int glyphCount;
     1649        int maxGlyphs;
     1650
     1651        QFixed minw;
     1652        QFixed softHyphenWidth;
     1653        QFixed rightBearing;
     1654
     1655        bool manualWrap;
     1656
     1657        bool checkFullOtherwiseExtend(QScriptLine &line);
     1658    };
     1659
     1660inline bool LineBreakHelper::checkFullOtherwiseExtend(QScriptLine &line)
     1661{       
    15611662    LB_DEBUG("possible break width %f, spacew=%f", tmpData.textWidth.toReal(), spaceData.textWidth.toReal());
    1562     if (line.length && !manualWrap &&
    1563         (line.textWidth + tmpData.textWidth + spaceData.textWidth + softHyphenWidth > line.width || glyphCount > maxGlyphs))
     1663
     1664    QFixed newWidth = line.textWidth + tmpData.textWidth + spaceData.textWidth + softHyphenWidth + rightBearing;
     1665    if (line.length && !manualWrap && (newWidth > line.width || glyphCount > maxGlyphs))
    15641666        return true;
     1667
    15651668    minw = qMax(minw, tmpData.textWidth);
    15661669    line += tmpData;
    15671670    line.textWidth += spaceData.textWidth;
     1671
    15681672    line.length += spaceData.length;
    15691673    tmpData.textWidth = 0;
     
    15711675    spaceData.textWidth = 0;
    15721676    spaceData.length = 0;
     1677
    15731678    return false;
    15741679}
    15751680
     1681} // anonymous namespace
     1682
     1683
    15761684static inline void addNextCluster(int &pos, int end, QScriptLine &line, int &glyphCount,
    1577                                   const QScriptItem &current, const unsigned short *logClusters, const QGlyphLayout &glyphs)
     1685                                  const QScriptItem &current, const unsigned short *logClusters,
     1686                                  const QGlyphLayout &glyphs)
    15781687{
    15791688    int glyphPosition = logClusters[pos];
     
    16081717    Q_ASSERT(line.from < eng->layoutData->string.length());
    16091718
     1719    LineBreakHelper lbh;
     1720
     1721    lbh.maxGlyphs = maxGlyphs;
     1722
    16101723    QTextOption::WrapMode wrapMode = eng->option.wrapMode();
    16111724    bool breakany = (wrapMode == QTextOption::WrapAnywhere);
    1612     bool manualWrap = (wrapMode == QTextOption::ManualWrap || wrapMode == QTextOption::NoWrap);
     1725    lbh.manualWrap = (wrapMode == QTextOption::ManualWrap || wrapMode == QTextOption::NoWrap);
    16131726
    16141727    // #### binary search!
     
    16201733    }
    16211734
    1622     QFixed minw = 0;
    1623     int glyphCount = 0;
    1624 
    16251735    LB_DEBUG("from: %d: item=%d, total %d, width available %f", line.from, newItem, eng->layoutData->items.size(), line.width.toReal());
    1626     QScriptLine tmpData;
    1627     QScriptLine spaceData;
    16281736
    16291737    Qt::Alignment alignment = eng->option.alignment();
     
    16341742    QGlyphLayout glyphs;
    16351743    const unsigned short *logClusters = eng->layoutData->logClustersPtr;
     1744
    16361745    while (newItem < eng->layoutData->items.size()) {
     1746        lbh.rightBearing = 0;
     1747        lbh.softHyphenWidth = 0;
    16371748        if (newItem != item) {
    16381749            item = newItem;
     
    16491760        const QScriptItem &current = eng->layoutData->items[item];
    16501761
    1651         tmpData.ascent = qMax(tmpData.ascent, current.ascent);
    1652         tmpData.descent = qMax(tmpData.descent, current.descent);
     1762        lbh.tmpData.leading = qMax(lbh.tmpData.leading + lbh.tmpData.ascent,
     1763                                   current.leading + current.ascent) - qMax(lbh.tmpData.ascent,
     1764                                                                            current.ascent);
     1765        lbh.tmpData.ascent = qMax(lbh.tmpData.ascent, current.ascent);
     1766        lbh.tmpData.descent = qMax(lbh.tmpData.descent, current.descent);
    16531767
    16541768        if (current.analysis.flags == QScriptAnalysis::Tab && (alignment & (Qt::AlignLeft | Qt::AlignRight | Qt::AlignCenter | Qt::AlignJustify))) {
    1655             if (checkFullOtherwiseExtend(line, tmpData, spaceData, glyphCount, maxGlyphs, minw, manualWrap))
     1769            if (lbh.checkFullOtherwiseExtend(line))
    16561770                goto found;
    16571771
    1658             QFixed x = line.x + line.textWidth + tmpData.textWidth + spaceData.textWidth;
    1659             spaceData.textWidth += eng->calculateTabWidth(item, x);
    1660             spaceData.length++;
     1772            QFixed x = line.x + line.textWidth + lbh.tmpData.textWidth + lbh.spaceData.textWidth;
     1773            QFixed tabWidth = eng->calculateTabWidth(item, x);
     1774
     1775            lbh.spaceData.textWidth += tabWidth;
     1776            lbh.spaceData.length++;
    16611777            newItem = item + 1;
    1662             ++glyphCount;
    1663             if (checkFullOtherwiseExtend(line, tmpData, spaceData, glyphCount, maxGlyphs, minw, manualWrap))
     1778
     1779            QFixed averageCharWidth = eng->fontEngine(current)->averageCharWidth();
     1780            lbh.glyphCount += qRound(tabWidth / averageCharWidth);
     1781
     1782            if (lbh.checkFullOtherwiseExtend(line))
    16641783                goto found;
    16651784        } else if (current.analysis.flags == QScriptAnalysis::LineOrParagraphSeparator) {
    16661785            // if the line consists only of the line separator make sure
    16671786            // we have a sane height
    1668             if (!line.length && !tmpData.length)
     1787            if (!line.length && !lbh.tmpData.length)
    16691788                line.setDefaultHeight(eng);
    16701789            if (eng->option.flags() & QTextOption::ShowLineAndParagraphSeparators) {
    1671                 addNextCluster(pos, end, tmpData, glyphCount, current, logClusters, glyphs);
     1790                addNextCluster(pos, end, lbh.tmpData, lbh.glyphCount,
     1791                               current, logClusters, glyphs);
    16721792            } else {
    1673                 tmpData.length++;
     1793                lbh.tmpData.length++;
    16741794            }
    1675             line += tmpData;
     1795            line += lbh.tmpData;
    16761796            goto found;
    16771797        } else if (current.analysis.flags == QScriptAnalysis::Object) {
    1678             tmpData.length++;
     1798            lbh.tmpData.length++;
    16791799
    16801800            QTextFormat format = eng->formats()->format(eng->formatIndex(&eng->layoutData->items[item]));
     
    16821802                eng->docLayout()->positionInlineObject(QTextInlineObject(item, eng), eng->block.position() + current.position, format);
    16831803
    1684             tmpData.textWidth += current.width;
     1804            lbh.tmpData.textWidth += current.width;
    16851805
    16861806            newItem = item + 1;
    1687             ++glyphCount;
    1688             if (checkFullOtherwiseExtend(line, tmpData, spaceData, glyphCount, maxGlyphs, minw, manualWrap))
     1807            ++lbh.glyphCount;
     1808            if (lbh.checkFullOtherwiseExtend(line))
    16891809                goto found;
    16901810        } else if (attributes[pos].whiteSpace) {
    16911811            while (pos < end && attributes[pos].whiteSpace)
    1692                 addNextCluster(pos, end, spaceData, glyphCount, current, logClusters, glyphs);
    1693 
    1694             if (!manualWrap && spaceData.textWidth > line.width) {
    1695                 spaceData.textWidth = line.width; // ignore spaces that fall out of the line.
     1812                addNextCluster(pos, end, lbh.spaceData, lbh.glyphCount,
     1813                               current, logClusters, glyphs);
     1814
     1815            if (!lbh.manualWrap && lbh.spaceData.textWidth > line.width) {
     1816                lbh.spaceData.textWidth = line.width; // ignore spaces that fall out of the line.
    16961817                goto found;
    16971818            }
     
    16991820            bool sb_or_ws = false;
    17001821            do {
    1701                 addNextCluster(pos, end, tmpData, glyphCount, current, logClusters, glyphs);
     1822                addNextCluster(pos, end, lbh.tmpData, lbh.glyphCount,
     1823                               current, logClusters, glyphs);
    17021824
    17031825                if (attributes[pos].whiteSpace || attributes[pos-1].lineBreakType != HB_NoBreak) {
     
    17081830                }
    17091831            } while (pos < end);
    1710             minw = qMax(tmpData.textWidth, minw);
    1711 
    1712             QFixed softHyphenWidth;
     1832            lbh.minw = qMax(lbh.tmpData.textWidth, lbh.minw);
     1833
    17131834            if (pos && attributes[pos - 1].lineBreakType == HB_SoftHyphen) {
    17141835                // if we are splitting up a word because of
     
    17291850                //
    17301851                if (line.length)
    1731                     softHyphenWidth = glyphs.advances_x[logClusters[pos - 1]];
     1852                    lbh.softHyphenWidth = glyphs.advances_x[logClusters[pos - 1]];
    17321853                else if (breakany)
    1733                     tmpData.textWidth += glyphs.advances_x[logClusters[pos - 1]];
     1854                    lbh.tmpData.textWidth += glyphs.advances_x[logClusters[pos - 1]];
    17341855            }
    17351856
    1736             if ((sb_or_ws|breakany)
    1737                 && checkFullOtherwiseExtend(line, tmpData, spaceData, glyphCount, maxGlyphs, minw, manualWrap, softHyphenWidth)) {
     1857            // The actual width of the text needs to take the right bearing into account. The
     1858            // right bearing is left-ward, which means that if the rightmost pixel is to the right
     1859            // of the advance of the glyph, the bearing will be negative. We flip the sign
     1860            // for the code to be more readable. Logic borrowed from qfontmetrics.cpp.
     1861            if (pos) {
     1862                QFontEngine *fontEngine = eng->fontEngine(current);
     1863                glyph_t glyph = glyphs.glyphs[logClusters[pos - 1]];
     1864                glyph_metrics_t gi = fontEngine->boundingBox(glyph);
     1865                if (gi.isValid())
     1866                    lbh.rightBearing = qMax(QFixed(), -(gi.xoff - gi.x - gi.width));
     1867            }
     1868
     1869            if ((sb_or_ws|breakany) && lbh.checkFullOtherwiseExtend(line)) {
    17381870                if (!breakany) {
    1739                     line.textWidth += softHyphenWidth;
     1871                    line.textWidth += lbh.softHyphenWidth;
    17401872                }
     1873
     1874                line.textWidth += lbh.rightBearing;
     1875
    17411876                goto found;
    17421877            }
     
    17461881    }
    17471882    LB_DEBUG("reached end of line");
    1748     checkFullOtherwiseExtend(line, tmpData, spaceData, glyphCount, maxGlyphs, minw, manualWrap);
    1749 found:
     1883    lbh.checkFullOtherwiseExtend(line);
     1884    line.textWidth += lbh.rightBearing;
     1885
     1886found:       
    17501887    if (line.length == 0) {
    17511888        LB_DEBUG("no break available in line, adding temp: length %d, width %f, space: length %d, width %f",
    1752                tmpData.length, tmpData.textWidth.toReal(), spaceData.length, spaceData.textWidth.toReal());
    1753         line += tmpData;
     1889               lbh.tmpData.length, lbh.tmpData.textWidth.toReal(),
     1890               lbh.spaceData.length, lbh.spaceData.textWidth.toReal());
     1891        line += lbh.tmpData;
    17541892    }
    17551893
    17561894    LB_DEBUG("line length = %d, ascent=%f, descent=%f, textWidth=%f (spacew=%f)", line.length, line.ascent.toReal(),
    1757            line.descent.toReal(), line.textWidth.toReal(), spaceData.width.toReal());
     1895           line.descent.toReal(), line.textWidth.toReal(), lbh.spaceData.width.toReal());
    17581896    LB_DEBUG("        : '%s'", eng->layoutData->string.mid(line.from, line.length).toUtf8().data());
    17591897
    1760     if (manualWrap) {
     1898    if (lbh.manualWrap) {
    17611899        eng->minWidth = qMax(eng->minWidth, line.textWidth);
    17621900        eng->maxWidth = qMax(eng->maxWidth, line.textWidth);
    17631901    } else {
    1764         eng->minWidth = qMax(eng->minWidth, minw);
     1902        eng->minWidth = qMax(eng->minWidth, lbh.minw);
    17651903        eng->maxWidth += line.textWidth;
    17661904    }
    17671905
    17681906    if (line.textWidth > 0 && item < eng->layoutData->items.size())
    1769         eng->maxWidth += spaceData.textWidth;
     1907        eng->maxWidth += lbh.spaceData.textWidth;
    17701908    if (eng->option.flags() & QTextOption::IncludeTrailingSpaces)
    1771         line.textWidth += spaceData.textWidth;
    1772     line.length += spaceData.length;
    1773     if (spaceData.length)
     1909        line.textWidth += lbh.spaceData.textWidth;
     1910    line.length += lbh.spaceData.length;
     1911    if (lbh.spaceData.length)
    17741912        line.hasTrailingSpaces = true;
    17751913
     
    17781916
    17791917    if (eng->option.wrapMode() == QTextOption::WrapAtWordBoundaryOrAnywhere) {
    1780         if ((maxGlyphs != INT_MAX && glyphCount > maxGlyphs)
    1781             || (maxGlyphs == INT_MAX && line.textWidth > line.width)) {
     1918        if ((lbh.maxGlyphs != INT_MAX && lbh.glyphCount > lbh.maxGlyphs)
     1919            || (lbh.maxGlyphs == INT_MAX && line.textWidth > line.width)) {
    17821920
    17831921            eng->option.setWrapMode(QTextOption::WrapAnywhere);
    17841922            line.length = 0;
    17851923            line.textWidth = 0;
    1786             layout_helper(maxGlyphs);
     1924            layout_helper(lbh.maxGlyphs);
    17871925            eng->option.setWrapMode(QTextOption::WrapAtWordBoundaryOrAnywhere);
    17881926        }
     
    19132051{
    19142052    QBrush c = chf.foreground();
    1915     if (c.style() == Qt::NoBrush)
     2053    if (c.style() == Qt::NoBrush) {
    19162054        p->setPen(defaultPen);
     2055    }
    19172056
    19182057    QBrush bg = chf.background();
    1919     if (bg.style() != Qt::NoBrush)
     2058    if (bg.style() != Qt::NoBrush && !chf.property(SuppressBackground).toBool())
    19202059        p->fillRect(r, bg);
    1921     if (c.style() != Qt::NoBrush)
     2060    if (c.style() != Qt::NoBrush) {
    19222061        p->setPen(QPen(c, 0));
     2062    }
     2063
    19232064}
    19242065
     
    19342075    QPen pen = p->pen();
    19352076
    1936     bool noText = (selection && selection->format.foreground().style() == Qt::NoBrush);
     2077    bool noText = (selection && selection->format.property(SuppressText).toBool());
    19372078
    19382079    if (!line.length) {
     
    19522093
    19532094    QTextLineItemIterator iterator(eng, i, pos, selection);
    1954     const QFixed y = QFixed::fromReal(pos.y()) + line.y + line.ascent;
     2095    QFixed lineBase = line.base();
     2096
     2097    const QFixed y = QFixed::fromReal(pos.y()) + line.y + lineBase;
    19552098
    19562099    bool suppressColors = (eng->option.flags() & QTextOption::SuppressColors);
     
    19752118                format.merge(selection->format);
    19762119
    1977             setPenAndDrawBackground(p, pen, format, QRectF(iterator.x.toReal(), (y - line.ascent).toReal(),
     2120            setPenAndDrawBackground(p, pen, format, QRectF(iterator.x.toReal(), (y - lineBase).toReal(),
    19782121                                                           iterator.itemWidth.toReal(), line.height().toReal()));
    19792122
     
    19962139                    QFixed itemY = y - si.ascent;
    19972140                    if (format.verticalAlignment() == QTextCharFormat::AlignTop) {
    1998                         itemY = y - line.ascent;
     2141                        itemY = y - lineBase;
    19992142                    }
    20002143
  • trunk/src/gui/text/qtextlayout.h

    r2 r561  
    22**
    33** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
    4 ** Contact: Qt Software Information (qt-info@nokia.com)
     4** All rights reserved.
     5** Contact: Nokia Corporation (qt-info@nokia.com)
    56**
    67** This file is part of the QtGui module of the Qt Toolkit.
     
    2122** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    2223**
    23 ** In addition, as a special exception, Nokia gives you certain
    24 ** additional rights. These rights are described in the Nokia Qt LGPL
    25 ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
    26 ** package.
     24** In addition, as a special exception, Nokia gives you certain additional
     25** rights.  These rights are described in the Nokia Qt LGPL Exception
     26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
    2727**
    2828** GNU General Public License Usage
     
    3434** met: http://www.gnu.org/copyleft/gpl.html.
    3535**
    36 ** If you are unsure which license is appropriate for your use, please
    37 ** contact the sales department at qt-sales@nokia.com.
     36** If you have questions regarding the use of this file, please contact
     37** Nokia at qt-info@nokia.com.
    3838** $QT_END_LICENSE$
    3939**
     
    197197    qreal descent() const;
    198198    qreal height() const;
     199    qreal leading() const;
     200
     201    void setLeadingIncluded(bool included);
     202    bool leadingIncluded() const;
    199203
    200204    qreal naturalTextWidth() const;
  • trunk/src/gui/text/qtextlist.cpp

    r2 r561  
    22**
    33** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
    4 ** Contact: Qt Software Information (qt-info@nokia.com)
     4** All rights reserved.
     5** Contact: Nokia Corporation (qt-info@nokia.com)
    56**
    67** This file is part of the QtGui module of the Qt Toolkit.
     
    2122** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    2223**
    23 ** In addition, as a special exception, Nokia gives you certain
    24 ** additional rights. These rights are described in the Nokia Qt LGPL
    25 ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
    26 ** package.
     24** In addition, as a special exception, Nokia gives you certain additional
     25** rights.  These rights are described in the Nokia Qt LGPL Exception
     26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
    2727**
    2828** GNU General Public License Usage
     
    3434** met: http://www.gnu.org/copyleft/gpl.html.
    3535**
    36 ** If you are unsure which license is appropriate for your use, please
    37 ** contact the sales department at qt-sales@nokia.com.
     36** If you have questions regarding the use of this file, please contact
     37** Nokia at qt-info@nokia.com.
    3838** $QT_END_LICENSE$
    3939**
     
    6464    \brief The QTextList class provides a decorated list of items in a QTextDocument.
    6565
    66     \ingroup text
     66    \ingroup richtext-processing
    6767
    6868    A list contains a sequence of text blocks, each of which is marked with a
     
    130130/*!
    131131    Returns the number of items in the list.
    132 
    133     \sa isEmpty()
    134132*/
    135133int QTextList::count() const
     
    213211            }
    214212            break;
     213        case QTextListFormat::ListLowerRoman:
     214        case QTextListFormat::ListUpperRoman:
     215            {
     216                if (item < 5000) {
     217                    QByteArray romanNumeral;
     218
     219                    // works for up to 4999 items
     220                    static const char romanSymbolsLower[] = "iiivixxxlxcccdcmmmm";
     221                    static const char romanSymbolsUpper[] = "IIIVIXXXLXCCCDCMMMM";
     222                    QByteArray romanSymbols; // wrap to have "mid"
     223                    if (style == QTextListFormat::ListLowerRoman)
     224                        romanSymbols = QByteArray::fromRawData(romanSymbolsLower, sizeof(romanSymbolsLower));
     225                    else
     226                        romanSymbols = QByteArray::fromRawData(romanSymbolsUpper, sizeof(romanSymbolsUpper));
     227
     228                    int c[] = { 1, 4, 5, 9, 10, 40, 50, 90, 100, 400, 500, 900, 1000 };
     229                    int n = item;
     230                    for (int i = 12; i >= 0; n %= c[i], i--) {
     231                        int q = n / c[i];
     232                        if (q > 0) {
     233                            int startDigit = i + (i+3)/4;
     234                            int numDigits;
     235                            if (i % 4) {
     236                                // c[i] == 4|5|9|40|50|90|400|500|900
     237                                if ((i-2) % 4) {
     238                                    // c[i] == 4|9|40|90|400|900 => with substraction (IV, IX, XL, XC, ...)
     239                                    numDigits = 2;
     240                                }
     241                                else {
     242                                    // c[i] == 5|50|500 (V, L, D)
     243                                    numDigits = 1;
     244                                }
     245                            }
     246                            else {
     247                                // c[i] == 1|10|100|1000 (I, II, III, X, XX, ...)
     248                                numDigits = q;
     249                            }
     250
     251                            romanNumeral.append(romanSymbols.mid(startDigit, numDigits));
     252                        }
     253                    }
     254                    result = QString::fromLatin1(romanNumeral);
     255                }
     256                else {
     257                    result = QLatin1String("?");
     258                }
     259
     260            }
     261            break;
    215262        default:
    216263            Q_ASSERT(false);
  • trunk/src/gui/text/qtextlist.h

    r2 r561  
    22**
    33** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
    4 ** Contact: Qt Software Information (qt-info@nokia.com)
     4** All rights reserved.
     5** Contact: Nokia Corporation (qt-info@nokia.com)
    56**
    67** This file is part of the QtGui module of the Qt Toolkit.
     
    2122** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    2223**
    23 ** In addition, as a special exception, Nokia gives you certain
    24 ** additional rights. These rights are described in the Nokia Qt LGPL
    25 ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
    26 ** package.
     24** In addition, as a special exception, Nokia gives you certain additional
     25** rights.  These rights are described in the Nokia Qt LGPL Exception
     26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
    2727**
    2828** GNU General Public License Usage
     
    3434** met: http://www.gnu.org/copyleft/gpl.html.
    3535**
    36 ** If you are unsure which license is appropriate for your use, please
    37 ** contact the sales department at qt-sales@nokia.com.
     36** If you have questions regarding the use of this file, please contact
     37** Nokia at qt-info@nokia.com.
    3838** $QT_END_LICENSE$
    3939**
  • trunk/src/gui/text/qtextobject.cpp

    r2 r561  
    22**
    33** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
    4 ** Contact: Qt Software Information (qt-info@nokia.com)
     4** All rights reserved.
     5** Contact: Nokia Corporation (qt-info@nokia.com)
    56**
    67** This file is part of the QtGui module of the Qt Toolkit.
     
    2122** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    2223**
    23 ** In addition, as a special exception, Nokia gives you certain
    24 ** additional rights. These rights are described in the Nokia Qt LGPL
    25 ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
    26 ** package.
     24** In addition, as a special exception, Nokia gives you certain additional
     25** rights.  These rights are described in the Nokia Qt LGPL Exception
     26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
    2727**
    2828** GNU General Public License Usage
     
    3434** met: http://www.gnu.org/copyleft/gpl.html.
    3535**
    36 ** If you are unsure which license is appropriate for your use, please
    37 ** contact the sales department at qt-sales@nokia.com.
     36** If you have questions regarding the use of this file, please contact
     37** Nokia at qt-info@nokia.com.
    3838** $QT_END_LICENSE$
    3939**
     
    6262    of objects that can group parts of a QTextDocument together.
    6363
    64     \ingroup text
     64    \ingroup richtext-processing
    6565
    6666    The common grouping text objects are lists (QTextList), frames
     
    7777    which acts as a factory method for creating text objects.
    7878
    79     \sa QTextDocument
     79    \sa QTextDocument, {Text Object Example}
    8080*/
    8181
     
    184184    a QTextDocument.
    185185
    186     \ingroup text
     186    \ingroup richtext-processing
    187187
    188188    Block groups can be used to organize blocks of text within a document.
     
    306306    \brief The QTextFrame class represents a frame in a QTextDocument.
    307307
    308     \ingroup text
     308    \ingroup richtext-processing
    309309
    310310    Text frames provide structure for the text in a document. They are used
     
    413413    : QTextObject(*new QTextFramePrivate(doc), doc)
    414414{
    415     Q_D(QTextFrame);
    416     d->fragment_start = 0;
    417     d->fragment_end = 0;
    418     d->parentFrame = 0;
    419     d->layoutData = 0;
    420415}
    421416
     
    436431    : QTextObject(p, doc)
    437432{
    438     Q_D(QTextFrame);
    439     d->fragment_start = 0;
    440     d->fragment_end = 0;
    441     d->parentFrame = 0;
    442     d->layoutData = 0;
    443433}
    444434
     
    610600    the contents of a QTextFrame.
    611601
    612     \ingroup text
     602    \ingroup richtext-processing
    613603
    614604    A frame consists of an arbitrary sequence of \l{QTextBlock}s and
     
    810800    \since 4.1
    811801
    812     \ingroup text
     802    \ingroup richtext-processing
    813803
    814804    QTextBlockUserData provides an abstract interface for container classes that are used
     
    840830    QTextDocument.
    841831
    842     \ingroup text
     832    \ingroup richtext-processing
    843833
    844834    A text block encapsulates a block or paragraph of text in a QTextDocument.
     
    935925    the contents of a QTextBlock.
    936926
    937     \ingroup text
     927    \ingroup richtext-processing
    938928
    939929    A block consists of a sequence of text fragments. This class provides
     
    13811371Sets the line count to \a count.
    13821372
    1383 /sa lineCount()
     1373\sa lineCount()
    13841374*/
    13851375void QTextBlock::setLineCount(int count)
     
    15361526    QTextDocument with a single QTextCharFormat.
    15371527
    1538     \ingroup text
     1528    \ingroup richtext-processing
    15391529
    15401530    A text fragment describes a piece of text that is stored with a single
  • trunk/src/gui/text/qtextobject.h

    r2 r561  
    22**
    33** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
    4 ** Contact: Qt Software Information (qt-info@nokia.com)
     4** All rights reserved.
     5** Contact: Nokia Corporation (qt-info@nokia.com)
    56**
    67** This file is part of the QtGui module of the Qt Toolkit.
     
    2122** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    2223**
    23 ** In addition, as a special exception, Nokia gives you certain
    24 ** additional rights. These rights are described in the Nokia Qt LGPL
    25 ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
    26 ** package.
     24** In addition, as a special exception, Nokia gives you certain additional
     25** rights.  These rights are described in the Nokia Qt LGPL Exception
     26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
    2727**
    2828** GNU General Public License Usage
     
    3434** met: http://www.gnu.org/copyleft/gpl.html.
    3535**
    36 ** If you are unsure which license is appropriate for your use, please
    37 ** contact the sales department at qt-sales@nokia.com.
     36** If you have questions regarding the use of this file, please contact
     37** Nokia at qt-info@nokia.com.
    3838** $QT_END_LICENSE$
    3939**
  • trunk/src/gui/text/qtextobject_p.h

    r2 r561  
    22**
    33** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
    4 ** Contact: Qt Software Information (qt-info@nokia.com)
     4** All rights reserved.
     5** Contact: Nokia Corporation (qt-info@nokia.com)
    56**
    67** This file is part of the QtGui module of the Qt Toolkit.
     
    2122** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    2223**
    23 ** In addition, as a special exception, Nokia gives you certain
    24 ** additional rights. These rights are described in the Nokia Qt LGPL
    25 ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
    26 ** package.
     24** In addition, as a special exception, Nokia gives you certain additional
     25** rights.  These rights are described in the Nokia Qt LGPL Exception
     26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
    2727**
    2828** GNU General Public License Usage
     
    3434** met: http://www.gnu.org/copyleft/gpl.html.
    3535**
    36 ** If you are unsure which license is appropriate for your use, please
    37 ** contact the sales department at qt-sales@nokia.com.
     36** If you have questions regarding the use of this file, please contact
     37** Nokia at qt-info@nokia.com.
    3838** $QT_END_LICENSE$
    3939**
     
    9595public:
    9696    QTextFramePrivate(QTextDocument *doc)
    97         : QTextObjectPrivate(doc)
     97        : QTextObjectPrivate(doc), fragment_start(0), fragment_end(0), parentFrame(0), layoutData(0)
    9898    {
    9999    }
  • trunk/src/gui/text/qtextodfwriter.cpp

    r2 r561  
    22**
    33** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
    4 ** Contact: Qt Software Information (qt-info@nokia.com)
     4** All rights reserved.
     5** Contact: Nokia Corporation (qt-info@nokia.com)
    56**
    67** This file is part of the QtGui module of the Qt Toolkit.
     
    2122** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    2223**
    23 ** In addition, as a special exception, Nokia gives you certain
    24 ** additional rights. These rights are described in the Nokia Qt LGPL
    25 ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
    26 ** package.
     24** In addition, as a special exception, Nokia gives you certain additional
     25** rights.  These rights are described in the Nokia Qt LGPL Exception
     26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
    2727**
    2828** GNU General Public License Usage
     
    3434** met: http://www.gnu.org/copyleft/gpl.html.
    3535**
    36 ** If you are unsure which license is appropriate for your use, please
    37 ** contact the sales department at qt-sales@nokia.com.
     36** If you have questions regarding the use of this file, please contact
     37** Nokia at qt-info@nokia.com.
    3838** $QT_END_LICENSE$
    3939**
     
    175175    case QTextListFormat::ListUpperAlpha:
    176176        return QString::fromLatin1("A");
     177    case QTextListFormat::ListLowerRoman:
     178        return QString::fromLatin1("i");
     179    case QTextListFormat::ListUpperRoman:
     180        return QString::fromLatin1("I");
    177181    default:
    178182    case QTextListFormat::ListStyleUndefined:
     
    296300            .arg(frag.fragment().charFormatIndex()));
    297301        bool escapeNextSpace = true;
    298         int precedingSpaces = 0, precedingTabs = 0;
     302        int precedingSpaces = 0;
    299303        int exportedIndex = 0;
    300304        for (int i=0; i <= fragmentText.count(); ++i) {
    301             bool isTab = false, isSpace = false;
    302             if (i < fragmentText.count()) {
     305            bool isSpace = false;
    303306                QChar character = fragmentText[i];
    304                 isTab = character.unicode() == '\t';
    305307                isSpace = character.unicode() == ' ';
    306                 if (character.unicode() == 0x2028) { // soft-return
    307                     writer.writeCharacters(fragmentText.mid(exportedIndex, i));
    308                     writer.writeEmptyElement(textNS, QString::fromLatin1("line-break"));
    309                     exportedIndex = i+1;
    310                     continue;
    311                 }
    312                 if (isSpace) {
    313                     ++precedingSpaces;
    314                     escapeNextSpace = true;
    315                 }
    316                 else if (isTab) {
    317                     precedingTabs++;
    318                 }
    319             }
     308
    320309            // find more than one space. -> <text:s text:c="2" />
    321310            if (!isSpace && escapeNextSpace && precedingSpaces > 1) {
     
    330319                exportedIndex = i;
    331320            }
    332             // find tabs.   ->  <text:tab text:tab-ref="3" />  or <text:tab/>
    333             if (!isTab && precedingTabs) {
    334                 writer.writeCharacters(fragmentText.mid(exportedIndex, i - precedingTabs - exportedIndex));
    335                 writer.writeEmptyElement(textNS, QString::fromLatin1("tab"));
    336                 if (precedingTabs > 1)
    337                     writer.writeAttribute(textNS, QString::fromLatin1("tab-ref"), QString::number(precedingTabs));
    338                 precedingTabs = 0;
    339                 exportedIndex = i;
     321
     322            if (i < fragmentText.count()) {
     323                if (character.unicode() == 0x2028) { // soft-return
     324                    //if (exportedIndex < i)
     325                        writer.writeCharacters(fragmentText.mid(exportedIndex, i - exportedIndex));
     326                    writer.writeEmptyElement(textNS, QString::fromLatin1("line-break"));
     327                    exportedIndex = i+1;
     328                    continue;
     329                } else if (character.unicode() == '\t') { // Tab
     330                    //if (exportedIndex < i)
     331                        writer.writeCharacters(fragmentText.mid(exportedIndex, i - exportedIndex));
     332                    writer.writeEmptyElement(textNS, QString::fromLatin1("tab"));
     333                    exportedIndex = i+1;
     334                    precedingSpaces = 0;
     335                } else if (isSpace) {
     336                    ++precedingSpaces;
     337                    escapeNextSpace = true;
     338                } else if (!isSpace) {
     339                    precedingSpaces = 0;
     340                }
    340341            }
    341             if (!isSpace && !isTab)
    342                 precedingSpaces = 0;
    343342        }
    344343
     
    449448
    450449    if (format.hasProperty(QTextFormat::BlockAlignment)) {
     450        const Qt::Alignment alignment = format.alignment() & Qt::AlignHorizontal_Mask;
    451451        QString value;
    452         if (format.alignment() == Qt::AlignLeading)
     452        if (alignment == Qt::AlignLeading)
    453453            value = QString::fromLatin1("start");
    454         else if (format.alignment() == Qt::AlignTrailing)
     454        else if (alignment == Qt::AlignTrailing)
    455455            value = QString::fromLatin1("end");
    456         else if (format.alignment() == (Qt::AlignLeft | Qt::AlignAbsolute))
     456        else if (alignment == (Qt::AlignLeft | Qt::AlignAbsolute))
    457457            value = QString::fromLatin1("left");
    458         else if (format.alignment() == (Qt::AlignRight | Qt::AlignAbsolute))
     458        else if (alignment == (Qt::AlignRight | Qt::AlignAbsolute))
    459459            value = QString::fromLatin1("right");
    460         else if (format.alignment() == Qt::AlignHCenter)
     460        else if (alignment == Qt::AlignHCenter)
    461461            value = QString::fromLatin1("center");
    462         else if (format.alignment() == Qt::AlignJustify)
     462        else if (alignment == Qt::AlignJustify)
    463463            value = QString::fromLatin1("justify");
    464464        else
     
    478478        writer.writeAttribute(foNS, QString::fromLatin1("margin-right"), pixelToPoint(qMax(qreal(0.), format.rightMargin())) );
    479479    if (format.hasProperty(QTextFormat::TextIndent))
    480         writer.writeAttribute(foNS, QString::fromLatin1("text-indent"), QString::number(format.textIndent()));
     480        writer.writeAttribute(foNS, QString::fromLatin1("text-indent"), pixelToPoint(format.textIndent()));
    481481    if (format.hasProperty(QTextFormat::PageBreakPolicy)) {
    482482        if (format.pageBreakPolicy() & QTextFormat::PageBreak_AlwaysBefore)
     
    484484        if (format.pageBreakPolicy() & QTextFormat::PageBreak_AlwaysAfter)
    485485            writer.writeAttribute(foNS, QString::fromLatin1("break-after"), QString::fromLatin1("page"));
     486    }
     487    if (format.hasProperty(QTextFormat::BackgroundBrush)) {
     488        QBrush brush = format.background();
     489        writer.writeAttribute(foNS, QString::fromLatin1("background-color"), brush.color().name());
    486490    }
    487491    if (format.hasProperty(QTextFormat::BlockNonBreakableLines))
     
    552556    }
    553557    if (format.hasProperty(QTextFormat::FontLetterSpacing))
    554         writer.writeAttribute(foNS, QString::fromLatin1("letter-spacing"), pixelToPoint(format.fontLetterSpacing()) );
     558        writer.writeAttribute(foNS, QString::fromLatin1("letter-spacing"), pixelToPoint(format.fontLetterSpacing()));
    555559    if (format.hasProperty(QTextFormat::FontWordSpacing))
    556         writer.writeAttribute(foNS, QString::fromLatin1("letter-spacing"), pixelToPoint(format.fontWordSpacing()) );
     560        writer.writeAttribute(foNS, QString::fromLatin1("word-spacing"), pixelToPoint(format.fontWordSpacing()));
    557561    if (format.hasProperty(QTextFormat::FontUnderline))
    558562        writer.writeAttribute(styleNS, QString::fromLatin1("text-underline-type"),
     
    611615    if (format.hasProperty(QTextFormat::ForegroundBrush)) {
    612616        QBrush brush = format.foreground();
    613         // TODO
    614617        writer.writeAttribute(foNS, QString::fromLatin1("color"), brush.color().name());
     618    }
     619    if (format.hasProperty(QTextFormat::BackgroundBrush)) {
     620        QBrush brush = format.background();
     621        writer.writeAttribute(foNS, QString::fromLatin1("background-color"), brush.color().name());
    615622    }
    616623
     
    625632    QTextListFormat::Style style = format.style();
    626633    if (style == QTextListFormat::ListDecimal || style == QTextListFormat::ListLowerAlpha
    627             || style == QTextListFormat::ListUpperAlpha) {
     634            || style == QTextListFormat::ListUpperAlpha
     635            || style == QTextListFormat::ListLowerRoman
     636            || style == QTextListFormat::ListUpperRoman) {
    628637        writer.writeStartElement(textNS, QString::fromLatin1("list-level-style-number"));
    629638        writer.writeAttribute(styleNS, QString::fromLatin1("num-format"), bulletChar(style));
  • trunk/src/gui/text/qtextodfwriter_p.h

    r2 r561  
    22**
    33** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
    4 ** Contact: Qt Software Information (qt-info@nokia.com)
     4** All rights reserved.
     5** Contact: Nokia Corporation (qt-info@nokia.com)
    56**
    67** This file is part of the QtGui module of the Qt Toolkit.
     
    2122** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    2223**
    23 ** In addition, as a special exception, Nokia gives you certain
    24 ** additional rights. These rights are described in the Nokia Qt LGPL
    25 ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
    26 ** package.
     24** In addition, as a special exception, Nokia gives you certain additional
     25** rights.  These rights are described in the Nokia Qt LGPL Exception
     26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
    2727**
    2828** GNU General Public License Usage
     
    3434** met: http://www.gnu.org/copyleft/gpl.html.
    3535**
    36 ** If you are unsure which license is appropriate for your use, please
    37 ** contact the sales department at qt-sales@nokia.com.
     36** If you have questions regarding the use of this file, please contact
     37** Nokia at qt-info@nokia.com.
    3838** $QT_END_LICENSE$
    3939**
  • trunk/src/gui/text/qtextoption.cpp

    r2 r561  
    22**
    33** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
    4 ** Contact: Qt Software Information (qt-info@nokia.com)
     4** All rights reserved.
     5** Contact: Nokia Corporation (qt-info@nokia.com)
    56**
    67** This file is part of the QtGui module of the Qt Toolkit.
     
    2122** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    2223**
    23 ** In addition, as a special exception, Nokia gives you certain
    24 ** additional rights. These rights are described in the Nokia Qt LGPL
    25 ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
    26 ** package.
     24** In addition, as a special exception, Nokia gives you certain additional
     25** rights.  These rights are described in the Nokia Qt LGPL Exception
     26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
    2727**
    2828** GNU General Public License Usage
     
    3434** met: http://www.gnu.org/copyleft/gpl.html.
    3535**
    36 ** If you are unsure which license is appropriate for your use, please
    37 ** contact the sales department at qt-sales@nokia.com.
     36** If you have questions regarding the use of this file, please contact
     37** Nokia at qt-info@nokia.com.
    3838** $QT_END_LICENSE$
    3939**
     
    118118    if (this == &o)
    119119        return *this;
    120     delete d; d = 0;
     120
     121    QTextOptionPrivate* dNew = 0;
     122    if (o.d)
     123        dNew = new QTextOptionPrivate(*o.d);
     124    delete d;
     125    d = dNew;
     126
    121127    align = o.align;
    122128    wordWrap = o.wordWrap;
     
    126132    f = o.f;
    127133    tab = o.tab;
    128     if (o.d)
    129         d = new QTextOptionPrivate(*o.d);
    130134    return *this;
    131135}
     
    198202    properties.
    199203
    200     \ingroup text
     204    \ingroup richtext-processing
    201205
    202206    QTextOption is used to encapsulate common rich text properties in a single
     
    342346    This enum holds the different types of tabulator
    343347
    344     \value LeftTab,     A left-tab
    345     \value RightTab,    A right-tab
    346     \value CenterTab,   A centered-tab
     348    \value LeftTab      A left-tab
     349    \value RightTab     A right-tab
     350    \value CenterTab    A centered-tab
    347351    \value DelimiterTab A tab stopping at a certain delimiter-character
    348352*/
  • trunk/src/gui/text/qtextoption.h

    r2 r561  
    22**
    33** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
    4 ** Contact: Qt Software Information (qt-info@nokia.com)
     4** All rights reserved.
     5** Contact: Nokia Corporation (qt-info@nokia.com)
    56**
    67** This file is part of the QtGui module of the Qt Toolkit.
     
    2122** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    2223**
    23 ** In addition, as a special exception, Nokia gives you certain
    24 ** additional rights. These rights are described in the Nokia Qt LGPL
    25 ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
    26 ** package.
     24** In addition, as a special exception, Nokia gives you certain additional
     25** rights.  These rights are described in the Nokia Qt LGPL Exception
     26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
    2727**
    2828** GNU General Public License Usage
     
    3434** met: http://www.gnu.org/copyleft/gpl.html.
    3535**
    36 ** If you are unsure which license is appropriate for your use, please
    37 ** contact the sales department at qt-sales@nokia.com.
     36** If you have questions regarding the use of this file, please contact
     37** Nokia at qt-info@nokia.com.
    3838** $QT_END_LICENSE$
    3939**
  • trunk/src/gui/text/qtexttable.cpp

    r2 r561  
    22**
    33** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
    4 ** Contact: Qt Software Information (qt-info@nokia.com)
     4** All rights reserved.
     5** Contact: Nokia Corporation (qt-info@nokia.com)
    56**
    67** This file is part of the QtGui module of the Qt Toolkit.
     
    2122** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    2223**
    23 ** In addition, as a special exception, Nokia gives you certain
    24 ** additional rights. These rights are described in the Nokia Qt LGPL
    25 ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
    26 ** package.
     24** In addition, as a special exception, Nokia gives you certain additional
     25** rights.  These rights are described in the Nokia Qt LGPL Exception
     26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
    2727**
    2828** GNU General Public License Usage
     
    3434** met: http://www.gnu.org/copyleft/gpl.html.
    3535**
    36 ** If you are unsure which license is appropriate for your use, please
    37 ** contact the sales department at qt-sales@nokia.com.
     36** If you have questions regarding the use of this file, please contact
     37** Nokia at qt-info@nokia.com.
    3838** $QT_END_LICENSE$
    3939**
     
    5959    cell in a QTextTable.
    6060
    61     \ingroup text
     61    \ingroup richtext-processing
    6262
    6363    Table cells are pieces of document structure that belong to a table.
     
    433433}
    434434
     435/*!
     436    /fn void QTextTablePrivate::update() const
     437
     438    This function is usually called when the table is "dirty".
     439    It seems to update all kind of table information.
     440
     441*/
    435442void QTextTablePrivate::update() const
    436443{
     
    440447//     qDebug(">>>> QTextTablePrivate::update, nRows=%d, nCols=%d", nRows, nCols);
    441448
    442     grid = (int *)realloc(grid, nRows*nCols*sizeof(int));
     449    grid = q_check_ptr((int *)realloc(grid, nRows*nCols*sizeof(int)));
    443450    memset(grid, 0, nRows*nCols*sizeof(int));
    444451
     
    464471
    465472        if (r + rowspan > nRows) {
    466             grid = (int *)realloc(grid, sizeof(int)*(r + rowspan)*nCols);
     473            grid = q_check_ptr((int *)realloc(grid, sizeof(int)*(r + rowspan)*nCols));
    467474            memset(grid + (nRows*nCols), 0, sizeof(int)*(r+rowspan-nRows)*nCols);
    468475            nRows = r + rowspan;
     
    493500    \brief The QTextTable class represents a table in a QTextDocument.
    494501
    495     \ingroup text
     502    \ingroup richtext-processing
    496503
    497504    A table is a group of cells ordered into rows and columns. Each table
     
    526533    the mergeCells() and splitCell() functions. However, only cells that span multiple
    527534    rows or columns can be split. (Merging or splitting does not increase or decrease
    528     the number of rows and columns.)
     535    the number of rows and columns.)
     536
     537    Note that if you have merged multiple columns and rows into one cell, you will not
     538    be able to split the merged cell into new cells spanning over more than one row
     539    or column. To be able to split cells spanning over several rows and columns you
     540    need to do this over several iterations.
    529541
    530542    \table 80%
  • trunk/src/gui/text/qtexttable.h

    r2 r561  
    22**
    33** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
    4 ** Contact: Qt Software Information (qt-info@nokia.com)
     4** All rights reserved.
     5** Contact: Nokia Corporation (qt-info@nokia.com)
    56**
    67** This file is part of the QtGui module of the Qt Toolkit.
     
    2122** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    2223**
    23 ** In addition, as a special exception, Nokia gives you certain
    24 ** additional rights. These rights are described in the Nokia Qt LGPL
    25 ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
    26 ** package.
     24** In addition, as a special exception, Nokia gives you certain additional
     25** rights.  These rights are described in the Nokia Qt LGPL Exception
     26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
    2727**
    2828** GNU General Public License Usage
     
    3434** met: http://www.gnu.org/copyleft/gpl.html.
    3535**
    36 ** If you are unsure which license is appropriate for your use, please
    37 ** contact the sales department at qt-sales@nokia.com.
     36** If you have questions regarding the use of this file, please contact
     37** Nokia at qt-info@nokia.com.
    3838** $QT_END_LICENSE$
    3939**
  • trunk/src/gui/text/qtexttable_p.h

    r2 r561  
    22**
    33** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
    4 ** Contact: Qt Software Information (qt-info@nokia.com)
     4** All rights reserved.
     5** Contact: Nokia Corporation (qt-info@nokia.com)
    56**
    67** This file is part of the QtGui module of the Qt Toolkit.
     
    2122** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    2223**
    23 ** In addition, as a special exception, Nokia gives you certain
    24 ** additional rights. These rights are described in the Nokia Qt LGPL
    25 ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
    26 ** package.
     24** In addition, as a special exception, Nokia gives you certain additional
     25** rights.  These rights are described in the Nokia Qt LGPL Exception
     26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
    2727**
    2828** GNU General Public License Usage
     
    3434** met: http://www.gnu.org/copyleft/gpl.html.
    3535**
    36 ** If you are unsure which license is appropriate for your use, please
    37 ** contact the sales department at qt-sales@nokia.com.
     36** If you have questions regarding the use of this file, please contact
     37** Nokia at qt-info@nokia.com.
    3838** $QT_END_LICENSE$
    3939**
     
    6363    Q_DECLARE_PUBLIC(QTextTable)
    6464public:
    65     QTextTablePrivate(QTextDocument *document) : QTextFramePrivate(document), grid(0), nRows(0), dirty(true), blockFragmentUpdates(false) {}
     65    QTextTablePrivate(QTextDocument *document) : QTextFramePrivate(document), grid(0), nRows(0), nCols(0), dirty(true), blockFragmentUpdates(false) {}
    6666    ~QTextTablePrivate();
    6767
  • trunk/src/gui/text/qzip.cpp

    r2 r561  
    22**
    33** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
    4 ** Contact: Qt Software Information (qt-info@nokia.com)
     4** All rights reserved.
     5** Contact: Nokia Corporation (qt-info@nokia.com)
    56**
    67** This file is part of the QtGui module of the Qt Toolkit.
     
    2122** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    2223**
    23 ** In addition, as a special exception, Nokia gives you certain
    24 ** additional rights. These rights are described in the Nokia Qt LGPL
    25 ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
    26 ** package.
     24** In addition, as a special exception, Nokia gives you certain additional
     25** rights.  These rights are described in the Nokia Qt LGPL Exception
     26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
    2727**
    2828** GNU General Public License Usage
     
    3434** met: http://www.gnu.org/copyleft/gpl.html.
    3535**
    36 ** If you are unsure which license is appropriate for your use, please
    37 ** contact the sales department at qt-sales@nokia.com.
     36** If you have questions regarding the use of this file, please contact
     37** Nokia at qt-info@nokia.com.
    3838** $QT_END_LICENSE$
    3939**
     
    5757#undef S_IFREG
    5858#define S_IFREG 0100000
    59 #  define S_ISDIR(x) ((x) & 0040000) > 0
    60 #  define S_ISREG(x) ((x) & 0170000) == S_IFREG
     59#  ifndef S_ISDIR
     60#    define S_ISDIR(x) ((x) & 0040000) > 0
     61#  endif
     62#  ifndef S_ISREG
     63#    define S_ISREG(x) ((x) & 0170000) == S_IFREG
     64#  endif
    6165#  define S_IFLNK 020000
    6266#  define S_ISLNK(x) ((x) & S_IFLNK) > 0
    63 #  define S_IRUSR 0400
    64 #  define S_IWUSR 0200
    65 #  define S_IXUSR 0100
     67#  ifndef S_IRUSR
     68#    define S_IRUSR 0400
     69#  endif
     70#  ifndef S_IWUSR
     71#    define S_IWUSR 0200
     72#  endif
     73#  ifndef S_IXUSR
     74#    define S_IXUSR 0100
     75#  endif
    6676#  define S_IRGRP 0040
    6777#  define S_IWGRP 0020
     
    696706QZipReader::QZipReader(const QString &archive, QIODevice::OpenMode mode)
    697707{
    698     QFile *f = new QFile(archive);
     708    QScopedPointer<QFile> f(new QFile(archive));
    699709    f->open(mode);
    700710    QZipReader::Status status;
     
    712722    }
    713723
    714     d = new QZipReaderPrivate(f, /*ownDevice=*/true);
     724    d = new QZipReaderPrivate(f.data(), /*ownDevice=*/true);
     725    f.take();
    715726    d->status = status;
    716727}
     
    762773    d->scanFiles();
    763774    QList<QZipReader::FileInfo> files;
    764     for (int i = 0; d && i < d->fileHeaders.size(); ++i) {
     775    for (int i = 0; i < d->fileHeaders.size(); ++i) {
    765776        QZipReader::FileInfo fi;
    766777        d->fillFileInfo(i, fi);
     
    970981QZipWriter::QZipWriter(const QString &fileName, QIODevice::OpenMode mode)
    971982{
    972     QFile *f = new QFile(fileName);
     983    QScopedPointer<QFile> f(new QFile(fileName));
    973984    f->open(mode);
    974985    QZipWriter::Status status;
     
    986997    }
    987998
    988     d = new QZipWriterPrivate(f, /*ownDevice=*/true);
     999    d = new QZipWriterPrivate(f.data(), /*ownDevice=*/true);
     1000    f.take();
    9891001    d->status = status;
    9901002}
  • trunk/src/gui/text/qzipreader_p.h

    r2 r561  
    22**
    33** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
    4 ** Contact: Qt Software Information (qt-info@nokia.com)
     4** All rights reserved.
     5** Contact: Nokia Corporation (qt-info@nokia.com)
    56**
    67** This file is part of the QtGui module of the Qt Toolkit.
     
    2122** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    2223**
    23 ** In addition, as a special exception, Nokia gives you certain
    24 ** additional rights. These rights are described in the Nokia Qt LGPL
    25 ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
    26 ** package.
     24** In addition, as a special exception, Nokia gives you certain additional
     25** rights.  These rights are described in the Nokia Qt LGPL Exception
     26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
    2727**
    2828** GNU General Public License Usage
     
    3434** met: http://www.gnu.org/copyleft/gpl.html.
    3535**
    36 ** If you are unsure which license is appropriate for your use, please
    37 ** contact the sales department at qt-sales@nokia.com.
     36** If you have questions regarding the use of this file, please contact
     37** Nokia at qt-info@nokia.com.
    3838** $QT_END_LICENSE$
    3939**
  • trunk/src/gui/text/qzipwriter_p.h

    r2 r561  
    22**
    33** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
    4 ** Contact: Qt Software Information (qt-info@nokia.com)
     4** All rights reserved.
     5** Contact: Nokia Corporation (qt-info@nokia.com)
    56**
    67** This file is part of the QtGui module of the Qt Toolkit.
     
    2122** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    2223**
    23 ** In addition, as a special exception, Nokia gives you certain
    24 ** additional rights. These rights are described in the Nokia Qt LGPL
    25 ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
    26 ** package.
     24** In addition, as a special exception, Nokia gives you certain additional
     25** rights.  These rights are described in the Nokia Qt LGPL Exception
     26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
    2727**
    2828** GNU General Public License Usage
     
    3434** met: http://www.gnu.org/copyleft/gpl.html.
    3535**
    36 ** If you are unsure which license is appropriate for your use, please
    37 ** contact the sales department at qt-sales@nokia.com.
     36** If you have questions regarding the use of this file, please contact
     37** Nokia at qt-info@nokia.com.
    3838** $QT_END_LICENSE$
    3939**
  • trunk/src/gui/text/text.pri

    r220 r561  
    8989        HEADERS += \
    9090                text/qfontengine_x11_p.h \
     91                text/qfontdatabase_x11.cpp \
    9192                text/qfontengine_ft_p.h
    9293        SOURCES += \
     
    117118}
    118119
     120symbian {
     121        SOURCES += \
     122                text/qfont_s60.cpp
     123        contains(QT_CONFIG, freetype) {
     124                SOURCES += \
     125                        text/qfontengine_ft.cpp
     126                HEADERS += \
     127                        text/qfontengine_ft_p.h
     128                DEFINES += \
     129                        QT_NO_FONTCONFIG
     130        } else {
     131                SOURCES += \
     132                        text/qfontengine_s60.cpp
     133                HEADERS += \
     134                        text/qfontengine_s60_p.h
     135                LIBS += -lfntstr -lecom
     136        }
     137}
     138
    119139contains(QT_CONFIG, freetype) {
    120140    SOURCES += \
    121         ../3rdparty/freetype/src/base/ftbase.c \
    122         ../3rdparty/freetype/src/base/ftbbox.c \
    123         ../3rdparty/freetype/src/base/ftdebug.c \
    124         ../3rdparty/freetype/src/base/ftglyph.c \
    125         ../3rdparty/freetype/src/base/ftinit.c \
    126         ../3rdparty/freetype/src/base/ftmm.c \
    127         ../3rdparty/freetype/src/base/fttype1.c \
    128         ../3rdparty/freetype/src/base/ftbitmap.c\
    129         ../3rdparty/freetype/src/bdf/bdf.c \
    130         ../3rdparty/freetype/src/cache/ftcache.c \
    131         ../3rdparty/freetype/src/cff/cff.c \
    132         ../3rdparty/freetype/src/cid/type1cid.c \
    133         ../3rdparty/freetype/src/gzip/ftgzip.c \
    134         ../3rdparty/freetype/src/pcf/pcf.c \
    135         ../3rdparty/freetype/src/pfr/pfr.c \
    136         ../3rdparty/freetype/src/psaux/psaux.c \
    137         ../3rdparty/freetype/src/pshinter/pshinter.c \
    138         ../3rdparty/freetype/src/psnames/psmodule.c \
    139         ../3rdparty/freetype/src/raster/raster.c \
    140         ../3rdparty/freetype/src/sfnt/sfnt.c \
    141         ../3rdparty/freetype/src/smooth/smooth.c \
    142         ../3rdparty/freetype/src/truetype/truetype.c \
    143         ../3rdparty/freetype/src/type1/type1.c \
    144         ../3rdparty/freetype/src/type42/type42.c \
    145         ../3rdparty/freetype/src/winfonts/winfnt.c \
    146         ../3rdparty/freetype/src/lzw/ftlzw.c\
    147         ../3rdparty/freetype/src/otvalid/otvalid.c\
    148         ../3rdparty/freetype/src/otvalid/otvbase.c\
    149         ../3rdparty/freetype/src/otvalid/otvgdef.c\
    150         ../3rdparty/freetype/src/otvalid/otvjstf.c\
    151         ../3rdparty/freetype/src/otvalid/otvcommn.c\
    152         ../3rdparty/freetype/src/otvalid/otvgpos.c\
    153         ../3rdparty/freetype/src/otvalid/otvgsub.c\
    154         ../3rdparty/freetype/src/otvalid/otvmod.c\
    155         ../3rdparty/freetype/src/autofit/afangles.c\
    156         ../3rdparty/freetype/src/autofit/afglobal.c\
    157         ../3rdparty/freetype/src/autofit/aflatin.c\
    158         ../3rdparty/freetype/src/autofit/afmodule.c\
    159         ../3rdparty/freetype/src/autofit/afdummy.c\
    160         ../3rdparty/freetype/src/autofit/afhints.c\
    161         ../3rdparty/freetype/src/autofit/afloader.c\
    162         ../3rdparty/freetype/src/autofit/autofit.c
    163 
    164     INCLUDEPATH += \
    165         ../3rdparty/freetype/src \
    166         ../3rdparty/freetype/include
    167 
    168     DEFINES += FT2_BUILD_LIBRARY
    169 
    170     os2 {
    171         SOURCES += ../3rdparty/freetype/src/base/ftsystem.c
    172         INCLUDEPATH += ../3rdparty/freetype/builds/os2
     141        ../3rdparty/freetype/src/base/ftbase.c \
     142        ../3rdparty/freetype/src/base/ftbbox.c \
     143        ../3rdparty/freetype/src/base/ftdebug.c \
     144        ../3rdparty/freetype/src/base/ftglyph.c \
     145        ../3rdparty/freetype/src/base/ftinit.c \
     146        ../3rdparty/freetype/src/base/ftmm.c \
     147        ../3rdparty/freetype/src/base/fttype1.c \
     148          ../3rdparty/freetype/src/base/ftbitmap.c\
     149        ../3rdparty/freetype/src/bdf/bdf.c \
     150        ../3rdparty/freetype/src/cache/ftcache.c \
     151        ../3rdparty/freetype/src/cff/cff.c \
     152        ../3rdparty/freetype/src/cid/type1cid.c \
     153        ../3rdparty/freetype/src/gzip/ftgzip.c \
     154        ../3rdparty/freetype/src/pcf/pcf.c \
     155        ../3rdparty/freetype/src/pfr/pfr.c \
     156        ../3rdparty/freetype/src/psaux/psaux.c \
     157        ../3rdparty/freetype/src/pshinter/pshinter.c \
     158        ../3rdparty/freetype/src/psnames/psmodule.c \
     159        ../3rdparty/freetype/src/raster/raster.c \
     160        ../3rdparty/freetype/src/sfnt/sfnt.c \
     161        ../3rdparty/freetype/src/smooth/smooth.c \
     162        ../3rdparty/freetype/src/truetype/truetype.c \
     163        ../3rdparty/freetype/src/type1/type1.c \
     164        ../3rdparty/freetype/src/type42/type42.c \
     165        ../3rdparty/freetype/src/winfonts/winfnt.c \
     166        ../3rdparty/freetype/src/lzw/ftlzw.c\
     167          ../3rdparty/freetype/src/otvalid/otvalid.c\
     168          ../3rdparty/freetype/src/otvalid/otvbase.c\
     169          ../3rdparty/freetype/src/otvalid/otvgdef.c\
     170          ../3rdparty/freetype/src/otvalid/otvjstf.c\
     171          ../3rdparty/freetype/src/otvalid/otvcommn.c\
     172          ../3rdparty/freetype/src/otvalid/otvgpos.c\
     173          ../3rdparty/freetype/src/otvalid/otvgsub.c\
     174          ../3rdparty/freetype/src/otvalid/otvmod.c\
     175          ../3rdparty/freetype/src/autofit/afangles.c\
     176          ../3rdparty/freetype/src/autofit/afglobal.c\
     177          ../3rdparty/freetype/src/autofit/aflatin.c\
     178          ../3rdparty/freetype/src/autofit/afmodule.c\
     179          ../3rdparty/freetype/src/autofit/afdummy.c\
     180          ../3rdparty/freetype/src/autofit/afhints.c\
     181          ../3rdparty/freetype/src/autofit/afloader.c\
     182          ../3rdparty/freetype/src/autofit/autofit.c
     183
     184    symbian {
     185        SOURCES += \
     186            ../3rdparty/freetype/src/base/ftsystem.c
     187        DEFINES += FT_CONFIG_OPTION_SYSTEM_ZLIB
     188    } os2 {
     189        SOURCES +=
     190            ../3rdparty/freetype/src/base/ftsystem.c
     191        INCLUDEPATH +=
     192            ../3rdparty/freetype/builds/os2
    173193    } else {
    174         SOURCES += ../3rdparty/freetype/builds/unix/ftsystem.c
    175         INCLUDEPATH += ../3rdparty/freetype/builds/unix
     194        SOURCES += \
     195            ../3rdparty/freetype/builds/unix/ftsystem.c
     196        INCLUDEPATH += \
     197            ../3rdparty/freetype/builds/unix
    176198        DEFINES += FT_CONFIG_OPTION_SYSTEM_ZLIB
    177199    }
    178200
     201    INCLUDEPATH += \
     202        ../3rdparty/freetype/src \
     203        ../3rdparty/freetype/include
     204
     205    DEFINES += FT2_BUILD_LIBRARY
     206   
    179207    embedded:CONFIG += opentype
    180208} else:contains(QT_CONFIG, system-freetype) {
     
    182210    # pull in the proper freetype2 include directory
    183211    include($$QT_SOURCE_TREE/config.tests/unix/freetype/freetype.pri)
    184     LIBS += -lfreetype
     212    LIBS_PRIVATE += -lfreetype
    185213} else {
    186214    DEFINES *= QT_NO_FREETYPE
Note: See TracChangeset for help on using the changeset viewer.