diff options
Diffstat (limited to 'src/gui/text')
-rw-r--r-- | src/gui/text/qcssparser.cpp | 44 | ||||
-rw-r--r-- | src/gui/text/qcssparser_p.h | 3 | ||||
-rw-r--r-- | src/gui/text/qfont.cpp | 3 | ||||
-rw-r--r-- | src/gui/text/qfontdatabase.cpp | 6 | ||||
-rw-r--r-- | src/gui/text/qfontdatabase.h | 1 | ||||
-rw-r--r-- | src/gui/text/qfontdatabase_x11.cpp | 33 | ||||
-rw-r--r-- | src/gui/text/qfontengine_qws.cpp | 51 | ||||
-rw-r--r-- | src/gui/text/qtextcontrol.cpp | 120 | ||||
-rw-r--r-- | src/gui/text/qtextcontrol_p_p.h | 20 | ||||
-rw-r--r-- | src/gui/text/qtextengine.cpp | 18 | ||||
-rw-r--r-- | src/gui/text/qtextengine_mac.cpp | 5 |
11 files changed, 218 insertions, 86 deletions
diff --git a/src/gui/text/qcssparser.cpp b/src/gui/text/qcssparser.cpp index 54ca7cc..052dc72 100644 --- a/src/gui/text/qcssparser.cpp +++ b/src/gui/text/qcssparser.cpp @@ -649,7 +649,7 @@ bool ValueExtractor::extractOutline(int *borders, QBrush *colors, BorderStyle *s return hit; } -static Qt::Alignment parseAlignment(const Value *values, int count) +static Qt::Alignment parseAlignment(const QCss::Value *values, int count) { Qt::Alignment a[2] = { 0, 0 }; for (int i = 0; i < qMin(2, count); i++) { @@ -672,7 +672,7 @@ static Qt::Alignment parseAlignment(const Value *values, int count) return a[0] | a[1]; } -static ColorData parseColorValue(Value v) +static ColorData parseColorValue(QCss::Value v) { if (v.type == Value::Identifier || v.type == Value::String) { v.variant.convert(QVariant::Color); @@ -706,7 +706,7 @@ static ColorData parseColorValue(Value v) if (!p.testExpr()) return ColorData(); - QVector<Value> colorDigits; + QVector<QCss::Value> colorDigits; if (!p.parseExpr(&colorDigits)) return ColorData(); @@ -738,7 +738,7 @@ static QColor colorFromData(const ColorData& c, const QPalette &pal) return QColor(); } -static BrushData parseBrushValue(const Value &v, const QPalette &pal) +static BrushData parseBrushValue(const QCss::Value &v, const QPalette &pal) { ColorData c = parseColorValue(v); if (c.type == ColorData::Color) { @@ -780,7 +780,7 @@ static BrushData parseBrushValue(const Value &v, const QPalette &pal) return BrushData(); parser.skipSpace(); if (attr.compare(QLatin1String("stop"), Qt::CaseInsensitive) == 0) { - Value stop, color; + QCss::Value stop, color; parser.next(); if (!parser.parseTerm(&stop)) return BrushData(); parser.skipSpace(); @@ -792,7 +792,7 @@ static BrushData parseBrushValue(const Value &v, const QPalette &pal) stops.append(QGradientStop(stop.variant.toReal(), colorFromData(cd, pal))); } else { parser.next(); - Value value; + QCss::Value value; (void)parser.parseTerm(&value); if (attr.compare(QLatin1String("spread"), Qt::CaseInsensitive) == 0) { spread = spreads.indexOf(value.variant.toString()); @@ -856,7 +856,7 @@ static QBrush brushFromData(const BrushData& c, const QPalette &pal) } } -static BorderStyle parseStyleValue(Value v) +static BorderStyle parseStyleValue(QCss::Value v) { if (v.type == Value::KnownIdentifier) { switch (v.variant.toInt()) { @@ -941,7 +941,7 @@ void ValueExtractor::borderValue(const Declaration &decl, int *width, QCss::Bord decl.d->parsed = QVariant::fromValue<BorderData>(data); } -static void parseShorthandBackgroundProperty(const QVector<Value> &values, BrushData *brush, QString *image, Repeat *repeat, Qt::Alignment *alignment, const QPalette &pal) +static void parseShorthandBackgroundProperty(const QVector<QCss::Value> &values, BrushData *brush, QString *image, Repeat *repeat, Qt::Alignment *alignment, const QPalette &pal) { *brush = BrushData(); *image = QString(); @@ -949,7 +949,7 @@ static void parseShorthandBackgroundProperty(const QVector<Value> &values, Brush *alignment = Qt::AlignTop | Qt::AlignLeft; for (int i = 0; i < values.count(); ++i) { - const Value &v = values.at(i); + const QCss::Value &v = values.at(i); if (v.type == Value::Uri) { *image = v.variant.toString(); continue; @@ -996,7 +996,7 @@ bool ValueExtractor::extractBackground(QBrush *brush, QString *image, Repeat *re const Declaration &decl = declarations.at(i); if (decl.d->values.isEmpty()) continue; - const Value &val = decl.d->values.at(0); + const QCss::Value &val = decl.d->values.at(0); switch (decl.d->propertyId) { case BackgroundColor: *brush = decl.brushValue(); @@ -1050,7 +1050,7 @@ bool ValueExtractor::extractBackground(QBrush *brush, QString *image, Repeat *re return hit; } -static bool setFontSizeFromValue(Value value, QFont *font, int *fontSizeAdjustment) +static bool setFontSizeFromValue(QCss::Value value, QFont *font, int *fontSizeAdjustment) { if (value.type == Value::KnownIdentifier) { bool valid = true; @@ -1087,7 +1087,7 @@ static bool setFontSizeFromValue(Value value, QFont *font, int *fontSizeAdjustme return valid; } -static bool setFontStyleFromValue(const Value &value, QFont *font) +static bool setFontStyleFromValue(const QCss::Value &value, QFont *font) { if (value.type != Value::KnownIdentifier) return false ; @@ -1100,7 +1100,7 @@ static bool setFontStyleFromValue(const Value &value, QFont *font) return false; } -static bool setFontWeightFromValue(const Value &value, QFont *font) +static bool setFontWeightFromValue(const QCss::Value &value, QFont *font) { if (value.type == Value::KnownIdentifier) { switch (value.variant.toInt()) { @@ -1121,12 +1121,12 @@ static bool setFontWeightFromValue(const Value &value, QFont *font) * and set it the \a font * \returns true if a family was extracted. */ -static bool setFontFamilyFromValues(const QVector<Value> &values, QFont *font, int start = 0) +static bool setFontFamilyFromValues(const QVector<QCss::Value> &values, QFont *font, int start = 0) { QString family; bool shouldAddSpace = false; for (int i = start; i < values.count(); ++i) { - const Value &v = values.at(i); + const QCss::Value &v = values.at(i); if (v.type == Value::TermOperatorComma) { family += QLatin1Char(','); shouldAddSpace = false; @@ -1146,7 +1146,7 @@ static bool setFontFamilyFromValues(const QVector<Value> &values, QFont *font, i return true; } -static void setTextDecorationFromValues(const QVector<Value> &values, QFont *font) +static void setTextDecorationFromValues(const QVector<QCss::Value> &values, QFont *font) { for (int i = 0; i < values.count(); ++i) { if (values.at(i).type != Value::KnownIdentifier) @@ -1165,7 +1165,7 @@ static void setTextDecorationFromValues(const QVector<Value> &values, QFont *fon } } -static void parseShorthandFontProperty(const QVector<Value> &values, QFont *font, int *fontSizeAdjustment) +static void parseShorthandFontProperty(const QVector<QCss::Value> &values, QFont *font, int *fontSizeAdjustment) { font->setStyle(QFont::StyleNormal); font->setWeight(QFont::Normal); @@ -1190,7 +1190,7 @@ static void parseShorthandFontProperty(const QVector<Value> &values, QFont *font } } -static void setFontVariantFromValue(const Value &value, QFont *font) +static void setFontVariantFromValue(const QCss::Value &value, QFont *font) { if (value.type == Value::KnownIdentifier) { switch (value.variant.toInt()) { @@ -1201,7 +1201,7 @@ static void setFontVariantFromValue(const Value &value, QFont *font) } } -static void setTextTransformFromValue(const Value &value, QFont *font) +static void setTextTransformFromValue(const QCss::Value &value, QFont *font) { if (value.type == Value::KnownIdentifier) { switch (value.variant.toInt()) { @@ -1226,7 +1226,7 @@ bool ValueExtractor::extractFont(QFont *font, int *fontSizeAdjustment) const Declaration &decl = declarations.at(i); if (decl.d->values.isEmpty()) continue; - const Value &val = decl.d->values.at(0); + const QCss::Value &val = decl.d->values.at(0); switch (decl.d->propertyId) { case FontSize: setFontSizeFromValue(val, font, fontSizeAdjustment); break; case FontStyle: setFontStyleFromValue(val, font); break; @@ -1411,7 +1411,7 @@ bool Declaration::realValue(qreal *real, const char *unit) const return ok; } -static bool intValueHelper(const Value &v, int *i, const char *unit) +static bool intValueHelper(const QCss::Value &v, int *i, const char *unit) { if (unit && v.type != Value::Length) return false; @@ -1460,7 +1460,7 @@ QRect Declaration::rectValue() const if (d->parsed.isValid()) return qvariant_cast<QRect>(d->parsed); - const Value &v = d->values.at(0); + const QCss::Value &v = d->values.at(0); if (v.type != Value::Function) return QRect(); QStringList func = v.variant.toStringList(); diff --git a/src/gui/text/qcssparser_p.h b/src/gui/text/qcssparser_p.h index 79c46b3..86bafc9 100644 --- a/src/gui/text/qcssparser_p.h +++ b/src/gui/text/qcssparser_p.h @@ -71,6 +71,9 @@ #if defined(Q_OS_VXWORKS) && defined(NONE) # undef NONE #endif +#if defined(Q_OS_INTEGRITY) +# undef Value +#endif QT_BEGIN_NAMESPACE diff --git a/src/gui/text/qfont.cpp b/src/gui/text/qfont.cpp index 084b7ac..64eb27a 100644 --- a/src/gui/text/qfont.cpp +++ b/src/gui/text/qfont.cpp @@ -139,6 +139,9 @@ bool QFontDef::exactMatch(const QFontDef &other) const QFontDatabase::parseFontName(family, this_foundry, this_family); QFontDatabase::parseFontName(other.family, other_foundry, other_family); + this_family = QFontDatabase::resolveFontFamilyAlias(this_family); + other_family = QFontDatabase::resolveFontFamilyAlias(other_family); + return (styleHint == other.styleHint && styleStrategy == other.styleStrategy && weight == other.weight diff --git a/src/gui/text/qfontdatabase.cpp b/src/gui/text/qfontdatabase.cpp index 8e92b1a..1e94bf5 100644 --- a/src/gui/text/qfontdatabase.cpp +++ b/src/gui/text/qfontdatabase.cpp @@ -1087,6 +1087,12 @@ QT_BEGIN_INCLUDE_NAMESPACE #elif defined(Q_OS_SYMBIAN) # include "qfontdatabase_s60.cpp" #endif +#if !defined(Q_WS_X11) +QString QFontDatabase::resolveFontFamilyAlias(const QString &family) +{ + return family; +} +#endif QT_END_INCLUDE_NAMESPACE static QtFontStyle *bestStyle(QtFontFoundry *foundry, const QtFontStyle::Key &styleKey) diff --git a/src/gui/text/qfontdatabase.h b/src/gui/text/qfontdatabase.h index 3e9483b..ae1130e 100644 --- a/src/gui/text/qfontdatabase.h +++ b/src/gui/text/qfontdatabase.h @@ -152,6 +152,7 @@ public: private: static void createDatabase(); static void parseFontName(const QString &name, QString &foundry, QString &family); + static QString resolveFontFamilyAlias(const QString &family); #if defined(Q_WS_QWS) || defined(Q_WS_QPA) || defined(Q_OS_SYMBIAN) static QFontEngine *findFont(int script, const QFontPrivate *fp, const QFontDef &request); #endif diff --git a/src/gui/text/qfontdatabase_x11.cpp b/src/gui/text/qfontdatabase_x11.cpp index 2186058..02b0148 100644 --- a/src/gui/text/qfontdatabase_x11.cpp +++ b/src/gui/text/qfontdatabase_x11.cpp @@ -1972,17 +1972,6 @@ void QFontDatabase::load(const QFontPrivate *d, int script) #ifndef QT_NO_FONTCONFIG } else if (X11->has_fontconfig) { fe = loadFc(d, script, req); - if (fe != 0 && fe->fontDef.pixelSize != req.pixelSize && mainThread && qt_is_gui_used) { - QFontEngine *xlfdFontEngine = loadXlfd(d->screen, script, req); - if (xlfdFontEngine->fontDef.family == fe->fontDef.family) { - delete fe; - fe = xlfdFontEngine; - } else { - delete xlfdFontEngine; - } - } - - #endif } else if (mainThread && qt_is_gui_used) { fe = loadXlfd(d->screen, script, req); @@ -2131,4 +2120,26 @@ bool QFontDatabase::supportsThreadedFontRendering() #endif } +QString QFontDatabase::resolveFontFamilyAlias(const QString &family) +{ +#if defined(QT_NO_FONTCONFIG) + return family; +#else + FcPattern *pattern = FcPatternCreate(); + if (!pattern) + return family; + + FcPatternAddString(pattern, FC_FAMILY, (const FcChar8 *) family.toUtf8().data()); + FcConfigSubstitute(0, pattern, FcMatchPattern); + FcDefaultSubstitute(pattern); + + FcChar8 *familyAfterSubstitution; + FcPatternGetString(pattern, FC_FAMILY, 0, &familyAfterSubstitution); + QString resolved = QString::fromUtf8((const char *) familyAfterSubstitution); + FcPatternDestroy(pattern); + + return resolved; +#endif +} + QT_END_NAMESPACE diff --git a/src/gui/text/qfontengine_qws.cpp b/src/gui/text/qfontengine_qws.cpp index 4802b94..b71c4a7 100644 --- a/src/gui/text/qfontengine_qws.cpp +++ b/src/gui/text/qfontengine_qws.cpp @@ -288,13 +288,16 @@ private: #else void readNode(QIODevice& f) { - uchar rw = f.getch(); - uchar cl = f.getch(); + char rw; + char cl; + f.getChar(&rw); + f.getChar(&cl); min = (rw << 8) | cl; - rw = f.getch(); - cl = f.getch(); + f.getChar(&rw); + f.getChar(&cl); max = (rw << 8) | cl; - int flags = f.getch(); + char flags; + f.getChar(&flags); if ( flags & 1 ) less = new QPFGlyphTree; else @@ -332,7 +335,7 @@ private: int n = max-min+1; for (int i=0; i<n; i++) { glyph[i].metrics = new QPFGlyphMetrics; - f.readBlock((char*)glyph[i].metrics, sizeof(QPFGlyphMetrics)); + f.read((char*)glyph[i].metrics, sizeof(QPFGlyphMetrics)); } if ( less ) less->readMetrics(f); @@ -365,7 +368,7 @@ private: //############### s = qt_screen->mapToDevice( s ); uint datasize = glyph[i].metrics->linestep * s.height(); glyph[i].data = new uchar[datasize]; // ### deleted? - f.readBlock((char*)glyph[i].data, datasize); + f.read((char*)glyph[i].data, datasize); } if ( less ) less->readData(f); @@ -385,6 +388,32 @@ public: size_t mmapLength; }; +#if defined(Q_OS_INTEGRITY) +static void *qt_mmap(void *start, size_t length, int /*prot*/, int /*flags*/, int fd, off_t offset) +{ + // INTEGRITY cannot mmap local files - load it into a local buffer + if (::lseek(fd, offset, SEEK_SET) == -1) { +# if defined(DEBUG_FONTENGINE) + perror("lseek failed"); +# endif + } + void *buf = malloc(length); + if (::read(fd, buf, length) != (ssize_t)length) { +# if defined(DEBUG_FONTENGINE) + perror("read failed"); +# endif + } + + return buf; +} +#else +static inline void *qt_mmap(void *start, size_t length, int prot, int flags, int fd, off_t offset) +{ + return mmap(start, length, prot, flags, fd, offset); +} +#endif + + QFontEngineQPF1::QFontEngineQPF1(const QFontDef&, const QString &fn) { @@ -395,16 +424,18 @@ QFontEngineQPF1::QFontEngineQPF1(const QFontDef&, const QString &fn) QT_STATBUF st; if ( QT_FSTAT( f, &st ) ) qFatal("Failed to stat %s",QFile::encodeName(fn).data()); - uchar* data = (uchar*)mmap( 0, // any address + uchar* data = (uchar*)qt_mmap( 0, // any address st.st_size, // whole file PROT_READ, // read-only memory -#if !defined(Q_OS_SOLARIS) && !defined(Q_OS_QNX4) && !defined(Q_OS_INTEGRITY) && !defined(Q_OS_VXWORKS) +#if defined(Q_OS_INTEGRITY) + 0, +#elif !defined(Q_OS_SOLARIS) && !defined(Q_OS_QNX4) && !defined(Q_OS_VXWORKS) MAP_FILE | MAP_PRIVATE, // swap-backed map from file #else MAP_PRIVATE, #endif f, 0 ); // from offset 0 of f -#if defined(Q_OS_QNX4) && !defined(MAP_FAILED) +#if !defined(MAP_FAILED) && (defined(Q_OS_QNX4) || defined(Q_OS_INTEGRITY)) #define MAP_FAILED ((void *)-1) #endif if ( !data || data == (uchar*)MAP_FAILED ) diff --git a/src/gui/text/qtextcontrol.cpp b/src/gui/text/qtextcontrol.cpp index e15c06d..46f1d62 100644 --- a/src/gui/text/qtextcontrol.cpp +++ b/src/gui/text/qtextcontrol.cpp @@ -933,15 +933,18 @@ void QTextControl::processEvent(QEvent *e, const QMatrix &matrix, QWidget *conte break; } case QEvent::MouseMove: { QMouseEvent *ev = static_cast<QMouseEvent *>(e); - d->mouseMoveEvent(ev->buttons(), matrix.map(ev->pos())); + d->mouseMoveEvent(ev, ev->button(), matrix.map(ev->pos()), ev->modifiers(), + ev->buttons(), ev->globalPos()); break; } case QEvent::MouseButtonRelease: { QMouseEvent *ev = static_cast<QMouseEvent *>(e); - d->mouseReleaseEvent(ev->button(), matrix.map(ev->pos())); + d->mouseReleaseEvent(ev, ev->button(), matrix.map(ev->pos()), ev->modifiers(), + ev->buttons(), ev->globalPos()); break; } case QEvent::MouseButtonDblClick: { QMouseEvent *ev = static_cast<QMouseEvent *>(e); - d->mouseDoubleClickEvent(e, ev->button(), matrix.map(ev->pos())); + d->mouseDoubleClickEvent(ev, ev->button(), matrix.map(ev->pos()), ev->modifiers(), + ev->buttons(), ev->globalPos()); break; } case QEvent::InputMethod: d->inputMethodEvent(static_cast<QInputMethodEvent *>(e)); @@ -1001,15 +1004,18 @@ void QTextControl::processEvent(QEvent *e, const QMatrix &matrix, QWidget *conte break; } case QEvent::GraphicsSceneMouseMove: { QGraphicsSceneMouseEvent *ev = static_cast<QGraphicsSceneMouseEvent *>(e); - d->mouseMoveEvent(ev->buttons(), matrix.map(ev->pos())); + d->mouseMoveEvent(ev, ev->button(), matrix.map(ev->pos()), ev->modifiers(), ev->buttons(), + ev->screenPos()); break; } case QEvent::GraphicsSceneMouseRelease: { QGraphicsSceneMouseEvent *ev = static_cast<QGraphicsSceneMouseEvent *>(e); - d->mouseReleaseEvent(ev->button(), matrix.map(ev->pos())); + d->mouseReleaseEvent(ev, ev->button(), matrix.map(ev->pos()), ev->modifiers(), ev->buttons(), + ev->screenPos()); break; } case QEvent::GraphicsSceneMouseDoubleClick: { QGraphicsSceneMouseEvent *ev = static_cast<QGraphicsSceneMouseEvent *>(e); - d->mouseDoubleClickEvent(e, ev->button(), matrix.map(ev->pos())); + d->mouseDoubleClickEvent(ev, ev->button(), matrix.map(ev->pos()), ev->modifiers(), ev->buttons(), + ev->screenPos()); break; } case QEvent::GraphicsSceneContextMenu: { QGraphicsSceneContextMenuEvent *ev = static_cast<QGraphicsSceneContextMenuEvent *>(e); @@ -1018,7 +1024,8 @@ void QTextControl::processEvent(QEvent *e, const QMatrix &matrix, QWidget *conte case QEvent::GraphicsSceneHoverMove: { QGraphicsSceneHoverEvent *ev = static_cast<QGraphicsSceneHoverEvent *>(e); - d->mouseMoveEvent(Qt::NoButton, matrix.map(ev->pos())); + d->mouseMoveEvent(ev, Qt::NoButton, matrix.map(ev->pos()), ev->modifiers(),Qt::NoButton, + ev->screenPos()); break; } case QEvent::GraphicsSceneDragEnter: { @@ -1488,6 +1495,11 @@ void QTextControlPrivate::mousePressEvent(QEvent *e, Qt::MouseButton button, con { Q_Q(QTextControl); + if (sendMouseEventToInputContext( + e, QEvent::MouseButtonPress, button, pos, modifiers, buttons, globalPos)) { + return; + } + if (interactionFlags & Qt::LinksAccessibleByMouse) { anchorOnMousePress = q->anchorAt(pos); @@ -1530,22 +1542,7 @@ void QTextControlPrivate::mousePressEvent(QEvent *e, Qt::MouseButton button, con return; } -#if !defined(QT_NO_IM) - QTextLayout *layout = cursor.block().layout(); - if (contextWidget && layout && !layout->preeditAreaText().isEmpty()) { - QInputContext *ctx = inputContext(); - if (ctx) { - QMouseEvent ev(QEvent::MouseButtonPress, contextWidget->mapFromGlobal(globalPos), globalPos, - button, buttons, modifiers); - ctx->mouseHandler(cursorPos - cursor.position(), &ev); - } - if (!layout->preeditAreaText().isEmpty()) { - e->ignore(); - return; - } - } -#endif - if (modifiers == Qt::ShiftModifier) { + if (modifiers == Qt::ShiftModifier && (interactionFlags & Qt::TextSelectableByMouse)) { if (wordSelectionEnabled && !selectedWordOnDoubleClick.hasSelection()) { selectedWordOnDoubleClick = cursor; selectedWordOnDoubleClick.select(QTextCursor::WordUnderCursor); @@ -1590,10 +1587,16 @@ void QTextControlPrivate::mousePressEvent(QEvent *e, Qt::MouseButton button, con hadSelectionOnMousePress = cursor.hasSelection(); } -void QTextControlPrivate::mouseMoveEvent(Qt::MouseButtons buttons, const QPointF &mousePos) +void QTextControlPrivate::mouseMoveEvent(QEvent *e, Qt::MouseButton button, const QPointF &mousePos, Qt::KeyboardModifiers modifiers, + Qt::MouseButtons buttons, const QPoint &globalPos) { Q_Q(QTextControl); + if (sendMouseEventToInputContext( + e, QEvent::MouseMove, button, mousePos, modifiers, buttons, globalPos)) { + return; + } + if (interactionFlags & Qt::LinksAccessibleByMouse) { QString anchor = q->anchorAt(mousePos); if (anchor != highlightedAnchor) { @@ -1623,12 +1626,6 @@ void QTextControlPrivate::mouseMoveEvent(Qt::MouseButtons buttons, const QPointF } const qreal mouseX = qreal(mousePos.x()); -#if !defined(QT_NO_IM) - QTextLayout *layout = cursor.block().layout(); - if (layout && !layout->preeditAreaText().isEmpty()) - return; -#endif - int newCursorPos = q->hitTest(mousePos, Qt::FuzzyHit); if (newCursorPos == -1) return; @@ -1642,7 +1639,7 @@ void QTextControlPrivate::mouseMoveEvent(Qt::MouseButtons buttons, const QPointF extendBlockwiseSelection(newCursorPos); else if (selectedWordOnDoubleClick.hasSelection()) extendWordwiseSelection(newCursorPos, mouseX); - else + else if (interactionFlags & Qt::TextSelectableByMouse) setCursorPosition(newCursorPos, QTextCursor::KeepAnchor); if (interactionFlags & Qt::TextEditable) { @@ -1666,10 +1663,16 @@ void QTextControlPrivate::mouseMoveEvent(Qt::MouseButtons buttons, const QPointF repaintOldAndNewSelection(oldSelection); } -void QTextControlPrivate::mouseReleaseEvent(Qt::MouseButton button, const QPointF &pos) +void QTextControlPrivate::mouseReleaseEvent(QEvent *e, Qt::MouseButton button, const QPointF &pos, Qt::KeyboardModifiers modifiers, + Qt::MouseButtons buttons, const QPoint &globalPos) { Q_Q(QTextControl); + if (sendMouseEventToInputContext( + e, QEvent::MouseButtonRelease, button, pos, modifiers, buttons, globalPos)) { + return; + } + const QTextCursor oldSelection = cursor; const int oldCursorPos = cursor.position(); @@ -1727,19 +1730,21 @@ void QTextControlPrivate::mouseReleaseEvent(Qt::MouseButton button, const QPoint } } -void QTextControlPrivate::mouseDoubleClickEvent(QEvent *e, Qt::MouseButton button, const QPointF &pos) +void QTextControlPrivate::mouseDoubleClickEvent(QEvent *e, Qt::MouseButton button, const QPointF &pos, Qt::KeyboardModifiers modifiers, + Qt::MouseButtons buttons, const QPoint &globalPos) { Q_Q(QTextControl); + + if (sendMouseEventToInputContext( + e, QEvent::MouseButtonDblClick, button, pos, modifiers, buttons, globalPos)) { + return; + } + if (button != Qt::LeftButton || !(interactionFlags & Qt::TextSelectableByMouse)) { e->ignore(); return; } -#if !defined(QT_NO_IM) - QTextLayout *layout = cursor.block().layout(); - if (layout && !layout->preeditAreaText().isEmpty()) - return; -#endif #ifndef QT_NO_DRAGANDDROP mightStartDrag = false; @@ -1768,6 +1773,45 @@ void QTextControlPrivate::mouseDoubleClickEvent(QEvent *e, Qt::MouseButton butto } } +bool QTextControlPrivate::sendMouseEventToInputContext( + QEvent *e, QEvent::Type eventType, Qt::MouseButton button, const QPointF &pos, + Qt::KeyboardModifiers modifiers, Qt::MouseButtons buttons, const QPoint &globalPos) +{ +#if !defined(QT_NO_IM) + Q_Q(QTextControl); + + QTextLayout *layout = cursor.block().layout(); + if (contextWidget && layout && !layout->preeditAreaText().isEmpty()) { + QInputContext *ctx = inputContext(); + int cursorPos = q->hitTest(pos, Qt::FuzzyHit) - cursor.position(); + + if (cursorPos < 0 || cursorPos > layout->preeditAreaText().length()) { + cursorPos = -1; + // don't send move events outside the preedit area + if (eventType == QEvent::MouseMove) + return true; + } + if (ctx) { + QMouseEvent ev(eventType, contextWidget->mapFromGlobal(globalPos), globalPos, + button, buttons, modifiers); + ctx->mouseHandler(cursorPos, &ev); + e->setAccepted(ev.isAccepted()); + } + if (!layout->preeditAreaText().isEmpty()) + return true; + } +#else + Q_UNUSED(e); + Q_UNUSED(eventType); + Q_UNUSED(button); + Q_UNUSED(pos); + Q_UNUSED(modifiers); + Q_UNUSED(buttons); + Q_UNUSED(globalPos); +#endif + return false; +} + void QTextControlPrivate::contextMenuEvent(const QPoint &screenPos, const QPointF &docPos, QWidget *contextWidget) { #ifdef QT_NO_CONTEXTMENU diff --git a/src/gui/text/qtextcontrol_p_p.h b/src/gui/text/qtextcontrol_p_p.h index ecd13ea..94670e2 100644 --- a/src/gui/text/qtextcontrol_p_p.h +++ b/src/gui/text/qtextcontrol_p_p.h @@ -135,9 +135,23 @@ public: Qt::KeyboardModifiers modifiers, Qt::MouseButtons buttons, const QPoint &globalPos); - void mouseMoveEvent(Qt::MouseButtons buttons, const QPointF &pos); - void mouseReleaseEvent(Qt::MouseButton button, const QPointF &pos); - void mouseDoubleClickEvent(QEvent *e, Qt::MouseButton button, const QPointF &pos); + void mouseMoveEvent(QEvent *e, Qt::MouseButton button, const QPointF &pos, + Qt::KeyboardModifiers modifiers, + Qt::MouseButtons buttons, + const QPoint &globalPos); + void mouseReleaseEvent(QEvent *e, Qt::MouseButton button, const QPointF &pos, + Qt::KeyboardModifiers modifiers, + Qt::MouseButtons buttons, + const QPoint &globalPos); + void mouseDoubleClickEvent(QEvent *e, Qt::MouseButton button, const QPointF &pos, + Qt::KeyboardModifiers modifiers, + Qt::MouseButtons buttons, + const QPoint &globalPos); + bool sendMouseEventToInputContext(QEvent *e, QEvent::Type eventType, Qt::MouseButton button, + const QPointF &pos, + Qt::KeyboardModifiers modifiers, + Qt::MouseButtons buttons, + const QPoint &globalPos); void contextMenuEvent(const QPoint &screenPos, const QPointF &docPos, QWidget *contextWidget); void focusEvent(QFocusEvent *e); #ifdef QT_KEYPAD_NAVIGATION diff --git a/src/gui/text/qtextengine.cpp b/src/gui/text/qtextengine.cpp index 415fa4b..a63fdbf 100644 --- a/src/gui/text/qtextengine.cpp +++ b/src/gui/text/qtextengine.cpp @@ -1385,6 +1385,15 @@ void QTextEngine::shape(int item) const } } +static inline void releaseCachedFontEngine(QFontEngine *fontEngine) +{ + if (fontEngine) { + fontEngine->ref.deref(); + if (fontEngine->cache_count == 0 && fontEngine->ref == 0) + delete fontEngine; + } +} + void QTextEngine::invalidate() { freeMemory(); @@ -1392,6 +1401,9 @@ void QTextEngine::invalidate() maxWidth = 0; if (specialData) specialData->resolvedFormatIndices.clear(); + + releaseCachedFontEngine(feCache.prevFontEngine); + releaseCachedFontEngine(feCache.prevScaledFontEngine); feCache.reset(); } @@ -1824,7 +1836,11 @@ QFontEngine *QTextEngine::fontEngine(const QScriptItem &si, QFixed *ascent, QFix scaledEngine = font.d->engineForScript(script); } feCache.prevFontEngine = engine; + if (engine) + engine->ref.ref(); feCache.prevScaledFontEngine = scaledEngine; + if (scaledEngine) + scaledEngine->ref.ref(); feCache.prevScript = script; feCache.prevPosition = si.position; feCache.prevLength = length(&si); @@ -1835,6 +1851,8 @@ QFontEngine *QTextEngine::fontEngine(const QScriptItem &si, QFixed *ascent, QFix else { engine = font.d->engineForScript(script); feCache.prevFontEngine = engine; + if (engine) + engine->ref.ref(); feCache.prevScript = script; feCache.prevPosition = -1; feCache.prevLength = -1; diff --git a/src/gui/text/qtextengine_mac.cpp b/src/gui/text/qtextengine_mac.cpp index c0a1e64..97e8c5b 100644 --- a/src/gui/text/qtextengine_mac.cpp +++ b/src/gui/text/qtextengine_mac.cpp @@ -607,8 +607,9 @@ void QTextEngine::shapeTextMac(int item) const bool stringToCMapFailed = false; if (!fe->stringToCMap(str, len, &g, &num_glyphs, flags, log_clusters, attributes())) { ensureSpace(num_glyphs); - stringToCMapFailed = fe->stringToCMap(str, len, &g, &num_glyphs, flags, log_clusters, - attributes()); + g = availableGlyphs(&si); + stringToCMapFailed = !fe->stringToCMap(str, len, &g, &num_glyphs, flags, log_clusters, + attributes()); } if (!stringToCMapFailed) { |