diff options
Diffstat (limited to 'src/gui')
42 files changed, 566 insertions, 509 deletions
diff --git a/src/gui/accessible/qaccessible.cpp b/src/gui/accessible/qaccessible.cpp index 9b8e44f003..1d1b64117e 100644 --- a/src/gui/accessible/qaccessible.cpp +++ b/src/gui/accessible/qaccessible.cpp @@ -51,6 +51,7 @@ #include <QtCore/qdebug.h> #include <QtCore/qmetaobject.h> +#include <QtCore/qhash.h> #include <private/qfactoryloader_p.h> QT_BEGIN_NAMESPACE @@ -430,6 +431,8 @@ Q_GLOBAL_STATIC_WITH_ARGS(QFactoryLoader, loader, #endif Q_GLOBAL_STATIC(QList<QAccessible::InterfaceFactory>, qAccessibleFactories) +typedef QHash<QString, QAccessiblePlugin*> QAccessiblePluginsHash; +Q_GLOBAL_STATIC(QAccessiblePluginsHash, qAccessiblePlugins); QAccessible::UpdateHandler QAccessible::updateHandler = 0; QAccessible::RootObjectHandler QAccessible::rootObjectHandler = 0; @@ -580,9 +583,13 @@ QAccessibleInterface *QAccessible::queryAccessibleInterface(QObject *object) if (!object) return 0; + // Create a QAccessibleInterface for the object class. Start by the most + // derived class and walk up the class hierarchy. const QMetaObject *mo = object->metaObject(); while (mo) { const QString cn = QLatin1String(mo->className()); + + // Check if the class has a InterfaceFactory installed. for (int i = qAccessibleFactories()->count(); i > 0; --i) { InterfaceFactory factory = qAccessibleFactories()->at(i - 1); if (QAccessibleInterface *iface = factory(cn, object)) @@ -590,8 +597,21 @@ QAccessibleInterface *QAccessible::queryAccessibleInterface(QObject *object) } #ifndef QT_NO_ACCESSIBILITY #ifndef QT_NO_LIBRARY - if (QAccessibleInterface * iface = qLoadPlugin1<QAccessibleInterface, QAccessiblePlugin>(loader(), cn, object)) - return iface; + // Find a QAccessiblePlugin (factory) for the class name. If there's + // no entry in the cache try to create it using the plugin loader. + if (!qAccessiblePlugins()->contains(cn)) { + QAccessiblePlugin *factory = 0; // 0 means "no plugin found". This is cached as well. + const int index = loader()->indexOf(cn); + if (index != -1) + factory = qobject_cast<QAccessiblePlugin *>(loader()->instance(index)); + qAccessiblePlugins()->insert(cn, factory); + } + + // At this point the cache should contain a valid factory pointer or 0: + Q_ASSERT(qAccessiblePlugins()->contains(cn)); + QAccessiblePlugin *factory = qAccessiblePlugins()->value(cn); + if (factory) + return factory->create(cn, object); #endif #endif mo = mo->superClass(); diff --git a/src/gui/accessible/qaccessible2.h b/src/gui/accessible/qaccessible2.h index 2f95094584..6081cde566 100644 --- a/src/gui/accessible/qaccessible2.h +++ b/src/gui/accessible/qaccessible2.h @@ -186,9 +186,9 @@ public: virtual bool isColumnSelected(int column) const = 0; // Returns a boolean value indicating whether the specified row is completely selected. virtual bool isRowSelected(int row) const = 0; - // Selects a row and unselects all previously selected rows. + // Selects a row and it might unselect all previously selected rows. virtual bool selectRow(int row) = 0; - // Selects a column and unselects all previously selected columns. + // Selects a column it might unselect all previously selected columns. virtual bool selectColumn(int column) = 0; // Unselects one row, leaving other selected rows selected (if any). virtual bool unselectRow(int row) = 0; diff --git a/src/gui/accessible/qaccessibleobject.cpp b/src/gui/accessible/qaccessibleobject.cpp index af8787ae80..bbdbb9ee68 100644 --- a/src/gui/accessible/qaccessibleobject.cpp +++ b/src/gui/accessible/qaccessibleobject.cpp @@ -55,39 +55,8 @@ class QAccessibleObjectPrivate { public: QPointer<QObject> object; - - QList<QByteArray> actionList() const; }; -QList<QByteArray> QAccessibleObjectPrivate::actionList() const -{ - QList<QByteArray> actionList; - - if (!object) - return actionList; - - const QMetaObject *mo = object->metaObject(); - Q_ASSERT(mo); - - QByteArray defaultAction = QMetaObject::normalizedSignature( - mo->classInfo(mo->indexOfClassInfo("DefaultSlot")).value()); - - for (int i = 0; i < mo->methodCount(); ++i) { - const QMetaMethod member = mo->method(i); - if (member.methodType() != QMetaMethod::Slot && member.access() != QMetaMethod::Public) - continue; - - if (!qstrcmp(member.tag(), "QACCESSIBLE_SLOT")) { - if (member.methodSignature() == defaultAction) - actionList.prepend(defaultAction); - else - actionList << member.methodSignature(); - } - } - - return actionList; -} - /*! \class QAccessibleObject \brief The QAccessibleObject class implements parts of the diff --git a/src/gui/doc/qtgui.qdocconf b/src/gui/doc/qtgui.qdocconf index a46aa9b3d1..469aa00472 100644 --- a/src/gui/doc/qtgui.qdocconf +++ b/src/gui/doc/qtgui.qdocconf @@ -3,21 +3,21 @@ include($QT_INSTALL_DOCS/global/qt-module-defaults.qdocconf) project = QtGui description = Qt GUI Reference Documentation url = http://qt-project.org/doc/qtgui -version = 5.0.1 +version = 5.1.0 examplesinstallpath = gui qhp.projects = QtGui qhp.QtGui.file = qtgui.qhp -qhp.QtGui.namespace = org.qt-project.qtgui.501 +qhp.QtGui.namespace = org.qt-project.qtgui.510 qhp.QtGui.virtualFolder = qtgui qhp.QtGui.indexTitle = Qt GUI qhp.QtGui.indexRoot = -qhp.QtGui.filterAttributes = qtgui 5.0.1 qtrefdoc -qhp.QtGui.customFilters.Qt.name = Qtgui 5.0.1 -qhp.QtGui.customFilters.Qt.filterAttributes = qtgui 5.0.1 +qhp.QtGui.filterAttributes = qtgui 5.1.0 qtrefdoc +qhp.QtGui.customFilters.Qt.name = Qtgui 5.1.0 +qhp.QtGui.customFilters.Qt.filterAttributes = qtgui 5.1.0 qhp.QtGui.subprojects = classes qhp.QtGui.subprojects.classes.title = C++ Classes diff --git a/src/gui/doc/snippets/code/src_gui_util_qvalidator.cpp b/src/gui/doc/snippets/code/src_gui_util_qvalidator.cpp index fbf58a8c09..f9a4ee4ad1 100644 --- a/src/gui/doc/snippets/code/src_gui_util_qvalidator.cpp +++ b/src/gui/doc/snippets/code/src_gui_util_qvalidator.cpp @@ -133,3 +133,46 @@ s = "README.1ST"; v.validate(s, pos); // Returns Acceptable s = "read me.txt"; v.validate(s, pos); // Returns Invalid s = "readm"; v.validate(s, pos); // Returns Intermediate //! [4] + +//! [5] +// regexp: optional '-' followed by between 1 and 3 digits +QRegularExpression rx("-?\\d{1,3}"); +QValidator *validator = new QRegularExpressionValidator(rx, this); + +QLineEdit *edit = new QLineEdit(this); +edit->setValidator(validator); +//! [5] + +//! [6] +// integers 1 to 9999 +QRegularExpression re("[1-9]\\d{0,3}"); +// the validator treats the regexp as "^[1-9]\\d{0,3}$" +QRegularExpressionValidator v(re, 0); +QString s; +int pos = 0; + +s = "0"; v.validate(s, pos); // returns Invalid +s = "12345"; v.validate(s, pos); // returns Invalid +s = "1"; v.validate(s, pos); // returns Acceptable + +re.setPattern("\\S+"); // one or more non-whitespace characters +v.setRegularExpression(re); +s = "myfile.txt"; v.validate(s, pos); // Returns Acceptable +s = "my file.txt"; v.validate(s, pos); // Returns Invalid + +// A, B or C followed by exactly five digits followed by W, X, Y or Z +re.setPattern("[A-C]\\d{5}[W-Z]"); +v.setRegularExpression(re); +s = "a12345Z"; v.validate(s, pos); // Returns Invalid +s = "A12345Z"; v.validate(s, pos); // Returns Acceptable +s = "B12"; v.validate(s, pos); // Returns Intermediate + +// match most 'readme' files +re.setPattern("read\\S?me(\.(txt|asc|1st))?"); +re.setPatternOptions(QRegularExpression::CaseInsensitiveOption); +v.setRegularExpression(re); +s = "readme"; v.validate(s, pos); // Returns Acceptable +s = "README.1ST"; v.validate(s, pos); // Returns Acceptable +s = "read me.txt"; v.validate(s, pos); // Returns Invalid +s = "readm"; v.validate(s, pos); // Returns Intermediate +//! [6] diff --git a/src/gui/image/qpixmap_raster.cpp b/src/gui/image/qpixmap_raster.cpp index f0cb69f3ec..554b31debf 100644 --- a/src/gui/image/qpixmap_raster.cpp +++ b/src/gui/image/qpixmap_raster.cpp @@ -353,7 +353,9 @@ void QRasterPlatformPixmap::createPixmapForImage(QImage &sourceImage, Qt::ImageC is_null = (w <= 0 || h <= 0); image.d->devicePixelRatio = sourceImage.devicePixelRatio(); + //ensure the pixmap and the image resulting from toImage() have the same cacheKey(); setSerialNumber(image.cacheKey() >> 32); + setDetachNumber(image.d->detach_no); } QImage* QRasterPlatformPixmap::buffer() diff --git a/src/gui/image/qplatformpixmap.cpp b/src/gui/image/qplatformpixmap.cpp index ba8a52d14f..1f40102cf0 100644 --- a/src/gui/image/qplatformpixmap.cpp +++ b/src/gui/image/qplatformpixmap.cpp @@ -173,6 +173,11 @@ void QPlatformPixmap::setSerialNumber(int serNo) ser_no = serNo; } +void QPlatformPixmap::setDetachNumber(int detNo) +{ + detach_no = detNo; +} + QImage QPlatformPixmap::toImage(const QRect &rect) const { if (rect.contains(QRect(0, 0, w, h))) diff --git a/src/gui/image/qplatformpixmap.h b/src/gui/image/qplatformpixmap.h index ded4bd30a9..b6438a95d7 100644 --- a/src/gui/image/qplatformpixmap.h +++ b/src/gui/image/qplatformpixmap.h @@ -132,6 +132,7 @@ public: protected: void setSerialNumber(int serNo); + void setDetachNumber(int detNo); int w; int h; int d; diff --git a/src/gui/kernel/qguiapplication.cpp b/src/gui/kernel/qguiapplication.cpp index 694ba3fc1b..698c26763a 100644 --- a/src/gui/kernel/qguiapplication.cpp +++ b/src/gui/kernel/qguiapplication.cpp @@ -2629,6 +2629,13 @@ static inline void applyCursor(QWindow *w, QCursor c) cursor->changeCursor(&c, w); } +static inline void unsetCursor(QWindow *w) +{ + if (const QScreen *screen = w->screen()) + if (QPlatformCursor *cursor = screen->handle()->cursor()) + cursor->changeCursor(0, w); +} + static inline void applyCursor(const QList<QWindow *> &l, const QCursor &c) { for (int i = 0; i < l.size(); ++i) { @@ -2642,8 +2649,13 @@ static inline void applyWindowCursor(const QList<QWindow *> &l) { for (int i = 0; i < l.size(); ++i) { QWindow *w = l.at(i); - if (w->handle() && w->type() != Qt::Desktop) - applyCursor(w, w->cursor()); + if (w->handle() && w->type() != Qt::Desktop) { + if (qt_window_private(w)->hasCursor) { + applyCursor(w, w->cursor()); + } else { + unsetCursor(w); + } + } } } diff --git a/src/gui/kernel/qplatformcursor.cpp b/src/gui/kernel/qplatformcursor.cpp index 16a59f5d07..c2f510b496 100644 --- a/src/gui/kernel/qplatformcursor.cpp +++ b/src/gui/kernel/qplatformcursor.cpp @@ -95,6 +95,10 @@ QList<QPlatformCursor *> QPlatformCursorPrivate::getInstances() \a windowCursor is a pointer to the QCursor that should be displayed. + To unset the cursor of \a window, 0 is passed. This means \a window does not have + a cursor set and the cursor of a the first parent window which has a cursor explicitly + set or the system default cursor should take effect. + \a window is a pointer to the window currently displayed at QCursor::pos(). Note that this may be 0 if the current position is not occupied by a displayed widget. diff --git a/src/gui/kernel/qplatformmenu.h b/src/gui/kernel/qplatformmenu.h index b02998940b..acaa57f071 100644 --- a/src/gui/kernel/qplatformmenu.h +++ b/src/gui/kernel/qplatformmenu.h @@ -103,6 +103,16 @@ public: virtual void setText(const QString &text) = 0; virtual void setEnabled(bool enabled) = 0; virtual void setVisible(bool visible) = 0; + virtual void setMinimumWidth(int width) { Q_UNUSED(width); } + virtual void setFont(const QFont &font) { Q_UNUSED(font); } + + virtual void showPopup(const QWindow *parentWindow, QPoint pos, const QPlatformMenuItem *item) + { + Q_UNUSED(parentWindow); + Q_UNUSED(pos); + Q_UNUSED(item); + setVisible(true); + } virtual QPlatformMenuItem *menuItemAt(int position) const = 0; virtual QPlatformMenuItem *menuItemForTag(quintptr tag) const = 0; diff --git a/src/gui/kernel/qwindow.cpp b/src/gui/kernel/qwindow.cpp index 27881c9db3..bf9d847eb0 100644 --- a/src/gui/kernel/qwindow.cpp +++ b/src/gui/kernel/qwindow.cpp @@ -284,7 +284,7 @@ void QWindow::setVisible(bool visible) } #ifndef QT_NO_CURSOR - if (visible) + if (visible && d->hasCursor) d->applyCursor(); #endif d->platformWindow->setVisible(visible); @@ -1946,13 +1946,7 @@ void QWindowPrivate::maybeQuitOnLastWindowClosed() void QWindow::setCursor(const QCursor &cursor) { Q_D(QWindow); - d->cursor = cursor; - // Only attempt to set cursor and emit signal if there is an actual platform cursor - if (d->screen->handle()->cursor()) { - d->applyCursor(); - QEvent event(QEvent::CursorChange); - QGuiApplication::sendEvent(this, &event); - } + d->setCursor(&cursor); } /*! @@ -1960,7 +1954,8 @@ void QWindow::setCursor(const QCursor &cursor) */ void QWindow::unsetCursor() { - setCursor(Qt::ArrowCursor); + Q_D(QWindow); + d->setCursor(0); } /*! @@ -1974,14 +1969,39 @@ QCursor QWindow::cursor() const return d->cursor; } +void QWindowPrivate::setCursor(const QCursor *newCursor) +{ + + Q_Q(QWindow); + if (newCursor) { + const Qt::CursorShape newShape = newCursor->shape(); + if (newShape <= Qt::LastCursor && hasCursor && newShape == cursor.shape()) + return; // Unchanged and no bitmap/custom cursor. + cursor = *newCursor; + hasCursor = true; + } else { + if (!hasCursor) + return; + cursor = QCursor(Qt::ArrowCursor); + hasCursor = false; + } + // Only attempt to set cursor and emit signal if there is an actual platform cursor + if (screen->handle()->cursor()) { + applyCursor(); + QEvent event(QEvent::CursorChange); + QGuiApplication::sendEvent(q, &event); + } +} + void QWindowPrivate::applyCursor() { Q_Q(QWindow); if (platformWindow) { if (QPlatformCursor *platformCursor = screen->handle()->cursor()) { - QCursor *oc = QGuiApplication::overrideCursor(); - QCursor c = oc ? *oc : cursor; - platformCursor->changeCursor(&c, q); + QCursor *c = QGuiApplication::overrideCursor(); + if (!c && hasCursor) + c = &cursor; + platformCursor->changeCursor(c, q); } } } diff --git a/src/gui/kernel/qwindow_p.h b/src/gui/kernel/qwindow_p.h index ed34693faa..e02b87e921 100644 --- a/src/gui/kernel/qwindow_p.h +++ b/src/gui/kernel/qwindow_p.h @@ -98,6 +98,7 @@ public: , screen(0) #ifndef QT_NO_CURSOR , cursor(Qt::ArrowCursor) + , hasCursor(false) #endif { isWindow = true; @@ -109,6 +110,7 @@ public: void maybeQuitOnLastWindowClosed(); #ifndef QT_NO_CURSOR + void setCursor(const QCursor *c = 0); void applyCursor(); #endif @@ -151,6 +153,7 @@ public: #ifndef QT_NO_CURSOR QCursor cursor; + bool hasCursor; #endif }; diff --git a/src/gui/opengl/qopenglpaintengine.cpp b/src/gui/opengl/qopenglpaintengine.cpp index 9fd8a7ada7..875fe4b4fb 100644 --- a/src/gui/opengl/qopenglpaintengine.cpp +++ b/src/gui/opengl/qopenglpaintengine.cpp @@ -1069,6 +1069,18 @@ void QOpenGL2PaintEngineExPrivate::resetClipIfNeeded() glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); } +bool QOpenGL2PaintEngineExPrivate::prepareForCachedGlyphDraw(const QFontEngineGlyphCache &cache) +{ + Q_Q(QOpenGL2PaintEngineEx); + + QTransform &transform = q->state()->matrix; + transform.scale(1.0 / cache.transform().m11(), 1.0 / cache.transform().m22()); + bool ret = prepareForDraw(false); + transform.scale(cache.transform().m11(), cache.transform().m22()); + + return ret; +} + bool QOpenGL2PaintEngineExPrivate::prepareForDraw(bool srcPixelsAreOpaque) { if (brushTextureDirty && mode != ImageDrawingMode && mode != ImageArrayDrawingMode) @@ -1407,11 +1419,9 @@ void QOpenGL2PaintEngineEx::drawStaticTextItem(QStaticTextItem *textItem) ensureActive(); QPainterState *s = state(); - float det = s->matrix.determinant(); - // don't try to cache huge fonts or vastly transformed fonts QFontEngine *fontEngine = textItem->fontEngine(); - if (shouldDrawCachedGlyphs(fontEngine, s->matrix) && det >= 0.25f && det <= 4.f) { + if (shouldDrawCachedGlyphs(fontEngine, s->matrix)) { QFontEngineGlyphCache::Type glyphType = fontEngine->glyphFormat >= 0 ? QFontEngineGlyphCache::Type(textItem->fontEngine()->glyphFormat) : d->glyphCacheType; @@ -1461,13 +1471,6 @@ void QOpenGL2PaintEngineEx::drawTextItem(const QPointF &p, const QTextItem &text QTransform::TransformationType txtype = s->matrix.type(); - float det = s->matrix.determinant(); - bool drawCached = txtype < QTransform::TxProject; - - // don't try to cache huge fonts or vastly transformed fonts - if (!shouldDrawCachedGlyphs(ti.fontEngine, s->matrix) || det < 0.25f || det > 4.f) - drawCached = false; - QFontEngineGlyphCache::Type glyphType = ti.fontEngine->glyphFormat >= 0 ? QFontEngineGlyphCache::Type(ti.fontEngine->glyphFormat) : d->glyphCacheType; @@ -1482,7 +1485,7 @@ void QOpenGL2PaintEngineEx::drawTextItem(const QPointF &p, const QTextItem &text } } - if (drawCached) { + if (shouldDrawCachedGlyphs(ti.fontEngine, s->matrix)) { QVarLengthArray<QFixedPoint> positions; QVarLengthArray<glyph_t> glyphs; QTransform matrix = QTransform::fromTranslate(p.x(), p.y()); @@ -1531,6 +1534,16 @@ namespace { // #define QT_OPENGL_DRAWCACHEDGLYPHS_INDEX_ARRAY_VBO +bool QOpenGL2PaintEngineEx::shouldDrawCachedGlyphs(QFontEngine *fontEngine, const QTransform &t) const +{ + float det = t.determinant(); + + // Don't try to cache huge fonts or vastly transformed fonts + return t.type() < QTransform::TxProject + && QPaintEngineEx::shouldDrawCachedGlyphs(fontEngine, t) + && det >= 0.25f && det <= 4.f; +} + void QOpenGL2PaintEngineExPrivate::drawCachedGlyphs(QFontEngineGlyphCache::Type glyphType, QStaticTextItem *staticTextItem) { @@ -1542,10 +1555,14 @@ void QOpenGL2PaintEngineExPrivate::drawCachedGlyphs(QFontEngineGlyphCache::Type bool recreateVertexArrays = false; QFontEngine *fe = staticTextItem->fontEngine(); + // We allow scaling, so that the glyph-cache will contain glyphs with the + // appropriate resolution in the case of displays with a device-pixel-ratio != 1. + QTransform transform = QTransform::fromScale(s->matrix.m11(), s->matrix.m22()); + QOpenGLTextureGlyphCache *cache = - (QOpenGLTextureGlyphCache *) fe->glyphCache(cacheKey, glyphType, QTransform()); + (QOpenGLTextureGlyphCache *) fe->glyphCache(cacheKey, glyphType, transform); if (!cache || cache->cacheType() != glyphType || cache->contextGroup() == 0) { - cache = new QOpenGLTextureGlyphCache(glyphType, QTransform()); + cache = new QOpenGLTextureGlyphCache(glyphType, transform); fe->setGlyphCache(cacheKey, cache); recreateVertexArrays = true; } @@ -1637,8 +1654,8 @@ void QOpenGL2PaintEngineExPrivate::drawCachedGlyphs(QFontEngineGlyphCache::Type if (c.isNull()) continue; - int x = qFloor(staticTextItem->glyphPositions[i].x) + c.baseLineX - margin; - int y = qRound(staticTextItem->glyphPositions[i].y) - c.baseLineY - margin; + int x = qFloor(staticTextItem->glyphPositions[i].x.toReal() * cache->transform().m11()) + c.baseLineX - margin; + int y = qRound(staticTextItem->glyphPositions[i].y.toReal() * cache->transform().m22()) - c.baseLineY - margin; vertexCoordinates->addQuad(QRectF(x, y, c.w, c.h)); textureCoordinates->addQuad(QRectF(c.x*dx, c.y*dy, c.w * dx, c.h * dy)); @@ -1711,9 +1728,9 @@ void QOpenGL2PaintEngineExPrivate::drawCachedGlyphs(QFontEngineGlyphCache::Type } compositionModeDirty = false; // I can handle this myself, thank you very much - prepareForDraw(false); // Text always causes src pixels to be transparent + prepareForCachedGlyphDraw(*cache); - // prepareForDraw() have set the opacity on the current shader, so the opacity state can now be reset. + // prepareForCachedGlyphDraw() have set the opacity on the current shader, so the opacity state can now be reset. if (compMode == QPainter::CompositionMode_Source) { q->state()->opacity = oldOpacity; opacityUniformDirty = true; @@ -1734,7 +1751,7 @@ void QOpenGL2PaintEngineExPrivate::drawCachedGlyphs(QFontEngineGlyphCache::Type } compositionModeDirty = false; // I can handle this myself, thank you very much - prepareForDraw(false); // Text always causes src pixels to be transparent + prepareForCachedGlyphDraw(*cache); glEnable(GL_BLEND); glBlendFunc(GL_ZERO, GL_ONE_MINUS_SRC_COLOR); @@ -1758,7 +1775,7 @@ void QOpenGL2PaintEngineExPrivate::drawCachedGlyphs(QFontEngineGlyphCache::Type } compositionModeDirty = false; - prepareForDraw(false); // Text always causes src pixels to be transparent + prepareForCachedGlyphDraw(*cache); glEnable(GL_BLEND); glBlendFunc(GL_ONE, GL_ONE); } @@ -1767,7 +1784,7 @@ void QOpenGL2PaintEngineExPrivate::drawCachedGlyphs(QFontEngineGlyphCache::Type // Greyscale/mono glyphs shaderManager->setMaskType(QOpenGLEngineShaderManager::PixelMask); - prepareForDraw(false); // Text always causes src pixels to be transparent + prepareForCachedGlyphDraw(*cache); } QOpenGLTextureGlyphCache::FilterMode filterMode = (s->matrix.type() > QTransform::TxTranslate)?QOpenGLTextureGlyphCache::Linear:QOpenGLTextureGlyphCache::Nearest; diff --git a/src/gui/opengl/qopenglpaintengine_p.h b/src/gui/opengl/qopenglpaintengine_p.h index 93e1b4232e..9c54eae3b3 100644 --- a/src/gui/opengl/qopenglpaintengine_p.h +++ b/src/gui/opengl/qopenglpaintengine_p.h @@ -157,7 +157,8 @@ public: void setRenderTextActive(bool); bool isNativePaintingActive() const; - bool supportsTransformations(QFontEngine *, const QTransform &) const { return true; } + bool requiresPretransformedGlyphPositions(QFontEngine *, const QTransform &) const { return false; } + bool shouldDrawCachedGlyphs(QFontEngine *, const QTransform &) const; private: Q_DISABLE_COPY(QOpenGL2PaintEngineEx) @@ -235,6 +236,7 @@ public: void setBrush(const QBrush& brush); void transferMode(EngineMode newMode); bool prepareForDraw(bool srcPixelsAreOpaque); // returns true if the program has changed + bool prepareForCachedGlyphDraw(const QFontEngineGlyphCache &cache); inline void useSimpleShader(); inline GLuint location(const QOpenGLEngineShaderManager::Uniform uniform) { return shaderManager->getUniformLocation(uniform); diff --git a/src/gui/painting/qdrawhelper.cpp b/src/gui/painting/qdrawhelper.cpp index 0f77ae6d86..906ef128fa 100644 --- a/src/gui/painting/qdrawhelper.cpp +++ b/src/gui/painting/qdrawhelper.cpp @@ -5368,7 +5368,7 @@ void qBlendTexture(int count, const QSpan *spans, void *userData) proc(count, spans, userData); } -template <class DST> +template <class DST> Q_STATIC_TEMPLATE_FUNCTION inline void qt_bitmapblit_template(QRasterBuffer *rasterBuffer, int x, int y, DST color, const uchar *map, diff --git a/src/gui/painting/qdrawhelper_p.h b/src/gui/painting/qdrawhelper_p.h index 258f130efc..eda2fc9242 100644 --- a/src/gui/painting/qdrawhelper_p.h +++ b/src/gui/painting/qdrawhelper_p.h @@ -382,7 +382,7 @@ static inline qreal qRadialDeterminant(qreal a, qreal b, qreal c) return (b * b) - (4 * a * c); } -template <class RadialFetchFunc> +template <class RadialFetchFunc> Q_STATIC_TEMPLATE_FUNCTION const uint * QT_FASTCALL qt_fetch_radial_gradient_template(uint *buffer, const Operator *op, const QSpanData *data, int y, int x, int length) { @@ -687,7 +687,7 @@ inline quint24::operator uint() const return data[2] | (data[1] << 8) | (data[0] << 16); } -template <class T> +template <class T> Q_STATIC_TEMPLATE_FUNCTION void qt_memfill(T *dest, T value, int count); template<> inline void qt_memfill(quint32 *dest, quint32 color, int count) @@ -728,7 +728,7 @@ inline void qt_memfill(T *dest, T value, int count) } } -template <class T> +template <class T> Q_STATIC_TEMPLATE_FUNCTION inline void qt_rectfill(T *dest, T value, int x, int y, int width, int height, int stride) { diff --git a/src/gui/painting/qpaintbuffer.cpp b/src/gui/painting/qpaintbuffer.cpp index 1a5a19a366..43bf1fd4ee 100644 --- a/src/gui/painting/qpaintbuffer.cpp +++ b/src/gui/painting/qpaintbuffer.cpp @@ -1752,7 +1752,7 @@ void QPainterReplayer::process(const QPaintBufferCommand &cmd) QRawFont rawFont; QRawFontPrivate *rawFontD = QRawFontPrivate::get(rawFont); QFontPrivate *fontD = QFontPrivate::get(font); - rawFontD->fontEngine = fontD->engineForScript(QUnicodeTables::Common); + rawFontD->fontEngine = fontD->engineForScript(QChar::Script_Common); rawFontD->fontEngine->ref.ref(); QGlyphRun glyphs; diff --git a/src/gui/painting/qpaintengine_raster.cpp b/src/gui/painting/qpaintengine_raster.cpp index f6a749f979..b9202e1612 100644 --- a/src/gui/painting/qpaintengine_raster.cpp +++ b/src/gui/painting/qpaintengine_raster.cpp @@ -3010,13 +3010,15 @@ void QRasterPaintEngine::drawStaticTextItem(QStaticTextItem *textItem) ensurePen(); ensureRasterState(); + QTransform matrix = state()->matrix; + QFontEngine *fontEngine = textItem->fontEngine(); - if (!supportsTransformations(fontEngine)) { + if (shouldDrawCachedGlyphs(fontEngine, matrix)) { drawCachedGlyphs(textItem->numGlyphs, textItem->glyphs, textItem->glyphPositions, fontEngine); - } else if (state()->matrix.type() < QTransform::TxProject) { + } else if (matrix.type() < QTransform::TxProject) { bool invertible; - QTransform invMat = state()->matrix.inverted(&invertible); + QTransform invMat = matrix.inverted(&invertible); if (!invertible) return; @@ -3055,7 +3057,7 @@ void QRasterPaintEngine::drawTextItem(const QPointF &p, const QTextItem &textIte QRasterPaintEngineState *s = state(); QTransform matrix = s->matrix; - if (!supportsTransformations(ti.fontEngine)) { + if (shouldDrawCachedGlyphs(ti.fontEngine, matrix)) { QVarLengthArray<QFixedPoint> positions; QVarLengthArray<glyph_t> glyphs; @@ -3299,21 +3301,25 @@ void QRasterPaintEngine::releaseDC(HDC) const /*! \internal */ -bool QRasterPaintEngine::supportsTransformations(QFontEngine *fontEngine) const +bool QRasterPaintEngine::requiresPretransformedGlyphPositions(QFontEngine *fontEngine, const QTransform &m) const { - const QTransform &m = state()->matrix; - return supportsTransformations(fontEngine, m); + // Cached glyphs always require pretransformed positions + if (shouldDrawCachedGlyphs(fontEngine, m)) + return true; + + // Otherwise let the base-class decide based on the transform + return QPaintEngineEx::requiresPretransformedGlyphPositions(fontEngine, m); } -/*! - \internal -*/ -bool QRasterPaintEngine::supportsTransformations(QFontEngine *fontEngine, const QTransform &m) const +bool QRasterPaintEngine::shouldDrawCachedGlyphs(QFontEngine *fontEngine, const QTransform &m) const { - if (fontEngine->supportsTransformations(m)) - return true; + // The font engine might not support filling the glyph cache + // with the given transform applied, in which case we need to + // fall back to the QPainterPath code-path. + if (!fontEngine->supportsTransformation(m)) + return false; - return !shouldDrawCachedGlyphs(fontEngine, m); + return QPaintEngineEx::shouldDrawCachedGlyphs(fontEngine, m); } /*! diff --git a/src/gui/painting/qpaintengine_raster_p.h b/src/gui/painting/qpaintengine_raster_p.h index e90cad6d8a..e5bb0406ae 100644 --- a/src/gui/painting/qpaintengine_raster_p.h +++ b/src/gui/painting/qpaintengine_raster_p.h @@ -231,8 +231,8 @@ public: QPoint coordinateOffset() const; - bool supportsTransformations(QFontEngine *fontEngine) const; - bool supportsTransformations(QFontEngine *fontEngine, const QTransform &m) const; + bool requiresPretransformedGlyphPositions(QFontEngine *fontEngine, const QTransform &m) const; + bool shouldDrawCachedGlyphs(QFontEngine *fontEngine, const QTransform &m) const; protected: QRasterPaintEngine(QRasterPaintEnginePrivate &d, QPaintDevice *); diff --git a/src/gui/painting/qpaintengineex.cpp b/src/gui/painting/qpaintengineex.cpp index 83b684da1e..5ca6075423 100644 --- a/src/gui/painting/qpaintengineex.cpp +++ b/src/gui/painting/qpaintengineex.cpp @@ -1081,14 +1081,9 @@ void QPaintEngineEx::drawStaticTextItem(QStaticTextItem *staticTextItem) } } -bool QPaintEngineEx::supportsTransformations(QFontEngine *fontEngine, const QTransform &m) const +bool QPaintEngineEx::requiresPretransformedGlyphPositions(QFontEngine *, const QTransform &t) const { - Q_UNUSED(fontEngine); - - if (!m.isAffine()) - return true; - - return false; + return t.type() >= QTransform::TxProject; } bool QPaintEngineEx::shouldDrawCachedGlyphs(QFontEngine *fontEngine, const QTransform &m) const diff --git a/src/gui/painting/qpaintengineex_p.h b/src/gui/painting/qpaintengineex_p.h index 399a6f63b0..4b578d8f97 100644 --- a/src/gui/painting/qpaintengineex_p.h +++ b/src/gui/painting/qpaintengineex_p.h @@ -164,7 +164,7 @@ public: IsEmulationEngine = 0x02 // If set, this object is a QEmulationEngine. }; virtual uint flags() const {return 0;} - virtual bool supportsTransformations(QFontEngine *fontEngine, const QTransform &m) const; + virtual bool requiresPretransformedGlyphPositions(QFontEngine *fontEngine, const QTransform &m) const; virtual bool shouldDrawCachedGlyphs(QFontEngine *fontEngine, const QTransform &m) const; protected: diff --git a/src/gui/painting/qpainter.cpp b/src/gui/painting/qpainter.cpp index 0ab2ab5589..a47b41d9cf 100644 --- a/src/gui/painting/qpainter.cpp +++ b/src/gui/painting/qpainter.cpp @@ -5552,13 +5552,13 @@ void QPainter::drawGlyphRun(const QPointF &position, const QGlyphRun &glyphRun) QVarLengthArray<QFixedPoint, 128> fixedPointPositions(count); QRawFontPrivate *fontD = QRawFontPrivate::get(font); - bool supportsTransformations = d->extended - ? d->extended->supportsTransformations(fontD->fontEngine, d->state->matrix) - : d->engine->type() == QPaintEngine::CoreGraphics || d->state->matrix.isAffine(); + bool engineRequiresPretransformedGlyphPositions = d->extended + ? d->extended->requiresPretransformedGlyphPositions(fontD->fontEngine, d->state->matrix) + : d->engine->type() != QPaintEngine::CoreGraphics && !d->state->matrix.isAffine(); for (int i=0; i<count; ++i) { QPointF processedPosition = position + glyphPositions[i]; - if (!supportsTransformations) + if (engineRequiresPretransformedGlyphPositions) processedPosition = d->state->transform().map(processedPosition); fixedPointPositions[i] = QFixedPoint::fromPointF(processedPosition); } @@ -5738,17 +5738,21 @@ void QPainter::drawStaticText(const QPointF &topLeftPosition, const QStaticText return; } - QFontEngine *fe = staticText_d->font.d->engineForScript(QUnicodeTables::Common); + QFontEngine *fe = staticText_d->font.d->engineForScript(QChar::Script_Common); if (fe->type() == QFontEngine::Multi) fe = static_cast<QFontEngineMulti *>(fe)->engine(0); - bool supportsTransformations = d->extended->supportsTransformations(fe, - d->state->matrix); - if (supportsTransformations && !staticText_d->untransformedCoordinates) { - staticText_d->untransformedCoordinates = true; - staticText_d->needsRelayout = true; - } else if (!supportsTransformations && staticText_d->untransformedCoordinates) { + + bool engineRequiresPretransform = d->extended->requiresPretransformedGlyphPositions(fe, d->state->matrix); + if (staticText_d->untransformedCoordinates && engineRequiresPretransform) { + // The coordinates are untransformed, and the engine can't deal with that + // nativly, so we have to pre-transform the static text. staticText_d->untransformedCoordinates = false; staticText_d->needsRelayout = true; + } else if (!staticText_d->untransformedCoordinates && !engineRequiresPretransform) { + // The coordinates are already transformed, but the engine can handle that + // nativly, so undo the transform of the static text. + staticText_d->untransformedCoordinates = true; + staticText_d->needsRelayout = true; } // Don't recalculate entire layout because of translation, rather add the dx and dy @@ -5845,7 +5849,7 @@ void QPainter::drawText(const QPointF &p, const QString &str, int tf, int justif int len = str.length(); int numGlyphs = len; QVarLengthGlyphLayoutArray glyphs(len); - QFontEngine *fontEngine = d->state->font.d->engineForScript(QUnicodeTables::Common); + QFontEngine *fontEngine = d->state->font.d->engineForScript(QChar::Script_Common); if (!fontEngine->stringToCMap(str.data(), len, &glyphs, &numGlyphs, 0)) { glyphs.resize(numGlyphs); if (!fontEngine->stringToCMap(str.data(), len, &glyphs, &numGlyphs, 0)) diff --git a/src/gui/text/qabstractfontengine_p.h b/src/gui/text/qabstractfontengine_p.h deleted file mode 100644 index e122cc5b4f..0000000000 --- a/src/gui/text/qabstractfontengine_p.h +++ /dev/null @@ -1,108 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/legal -** -** This file is part of the QtGui module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and Digia. For licensing terms and -** conditions see http://qt.digia.com/licensing. For further information -** use the contact form at http://qt.digia.com/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Digia gives you certain additional -** rights. These rights are described in the Digia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QABSTRACTFONTENGINE_P_H -#define QABSTRACTFONTENGINE_P_H - -// -// W A R N I N G -// ------------- -// -// This file is not part of the Qt API. It exists purely as an -// implementation detail. This header file may change from version to -// version without notice, or even be removed. -// -// We mean it. -// - -#include "qfontengine_p.h" -#include "qabstractfontengine_qws.h" - -QT_BEGIN_NAMESPACE - -class QCustomFontEngine; - -class QProxyFontEngine : public QFontEngine -{ - Q_OBJECT -public: - QProxyFontEngine(QAbstractFontEngine *engine, const QFontDef &def); - virtual ~QProxyFontEngine(); - - virtual bool stringToCMap(const QChar *str, int len, QGlyphLayout *glyphs, int *nglyphs, ShaperFlags flags) const; - virtual void recalcAdvances(QGlyphLayout *, ShaperFlags) const; - virtual QImage alphaMapForGlyph(glyph_t); - virtual void addGlyphsToPath(glyph_t *glyphs, QFixedPoint *positions, int nglyphs, QPainterPath *path, QTextItem::RenderFlags flags); - virtual glyph_metrics_t boundingBox(const QGlyphLayout &glyphs); - virtual glyph_metrics_t boundingBox(glyph_t glyph); - - virtual QFixed ascent() const; - virtual QFixed descent() const; - virtual QFixed leading() const; - virtual QFixed xHeight() const; - virtual QFixed averageCharWidth() const; - virtual QFixed lineThickness() const; - virtual QFixed underlinePosition() const; - virtual qreal maxCharWidth() const; - virtual qreal minLeftBearing() const; - virtual qreal minRightBearing() const; - virtual int glyphCount() const; - - virtual bool canRender(const QChar *string, int len); - - virtual Type type() const { return Proxy; } - virtual const char *name() const { return "proxy engine"; } - - virtual void draw(QPaintEngine *, qreal, qreal, const QTextItemInt &); - - inline QAbstractFontEngine::Capabilities capabilities() const - { return engineCapabilities; } - - bool drawAsOutline() const; - -private: - QAbstractFontEngine *engine; - QAbstractFontEngine::Capabilities engineCapabilities; -}; - -QT_END_NAMESPACE - -#endif diff --git a/src/gui/text/qfont.cpp b/src/gui/text/qfont.cpp index 72a24a4698..87ca5e4cfe 100644 --- a/src/gui/text/qfont.cpp +++ b/src/gui/text/qfont.cpp @@ -55,7 +55,6 @@ #include "qthread.h" #include "qthreadstorage.h" -#include <private/qunicodetables_p.h> #include "qfont_p.h" #include <private/qfontengine_p.h> #include <private/qpainter_p.h> @@ -207,8 +206,8 @@ extern QMutex *qt_fontdatabase_mutex(); QFontEngine *QFontPrivate::engineForScript(int script) const { QMutexLocker locker(qt_fontdatabase_mutex()); - if (script >= QUnicodeTables::Inherited) - script = QUnicodeTables::Common; + if (script <= QChar::Script_Latin) + script = QChar::Script_Common; if (engineData && engineData->fontCache != QFontCache::instance()) { // throw out engineData that came from a different thread engineData->ref.deref(); @@ -319,12 +318,12 @@ void QFontPrivate::resolve(uint mask, const QFontPrivate *other) QFontEngineData::QFontEngineData() : ref(1), fontCache(QFontCache::instance()) { - memset(engines, 0, QUnicodeTables::ScriptCount * sizeof(QFontEngine *)); + memset(engines, 0, QChar::ScriptCount * sizeof(QFontEngine *)); } QFontEngineData::~QFontEngineData() { - for (int i = 0; i < QUnicodeTables::ScriptCount; ++i) { + for (int i = 0; i < QChar::ScriptCount; ++i) { if (engines[i]) engines[i]->ref.deref(); engines[i] = 0; @@ -1667,7 +1666,7 @@ void QFont::setRawMode(bool enable) */ bool QFont::exactMatch() const { - QFontEngine *engine = d->engineForScript(QUnicodeTables::Common); + QFontEngine *engine = d->engineForScript(QChar::Script_Common); Q_ASSERT(engine != 0); return (d->rawMode ? engine->type() != QFontEngine::Box @@ -2363,7 +2362,7 @@ QFontInfo &QFontInfo::operator=(const QFontInfo &fi) */ QString QFontInfo::family() const { - QFontEngine *engine = d->engineForScript(QUnicodeTables::Common); + QFontEngine *engine = d->engineForScript(QChar::Script_Common); Q_ASSERT(engine != 0); return engine->fontDef.family; } @@ -2378,7 +2377,7 @@ QString QFontInfo::family() const */ QString QFontInfo::styleName() const { - QFontEngine *engine = d->engineForScript(QUnicodeTables::Common); + QFontEngine *engine = d->engineForScript(QChar::Script_Common); Q_ASSERT(engine != 0); return engine->fontDef.styleName; } @@ -2390,7 +2389,7 @@ QString QFontInfo::styleName() const */ int QFontInfo::pointSize() const { - QFontEngine *engine = d->engineForScript(QUnicodeTables::Common); + QFontEngine *engine = d->engineForScript(QChar::Script_Common); Q_ASSERT(engine != 0); return qRound(engine->fontDef.pointSize); } @@ -2402,7 +2401,7 @@ int QFontInfo::pointSize() const */ qreal QFontInfo::pointSizeF() const { - QFontEngine *engine = d->engineForScript(QUnicodeTables::Common); + QFontEngine *engine = d->engineForScript(QChar::Script_Common); Q_ASSERT(engine != 0); return engine->fontDef.pointSize; } @@ -2414,7 +2413,7 @@ qreal QFontInfo::pointSizeF() const */ int QFontInfo::pixelSize() const { - QFontEngine *engine = d->engineForScript(QUnicodeTables::Common); + QFontEngine *engine = d->engineForScript(QChar::Script_Common); Q_ASSERT(engine != 0); return engine->fontDef.pixelSize; } @@ -2426,7 +2425,7 @@ int QFontInfo::pixelSize() const */ bool QFontInfo::italic() const { - QFontEngine *engine = d->engineForScript(QUnicodeTables::Common); + QFontEngine *engine = d->engineForScript(QChar::Script_Common); Q_ASSERT(engine != 0); return engine->fontDef.style != QFont::StyleNormal; } @@ -2438,7 +2437,7 @@ bool QFontInfo::italic() const */ QFont::Style QFontInfo::style() const { - QFontEngine *engine = d->engineForScript(QUnicodeTables::Common); + QFontEngine *engine = d->engineForScript(QChar::Script_Common); Q_ASSERT(engine != 0); return (QFont::Style)engine->fontDef.style; } @@ -2450,7 +2449,7 @@ QFont::Style QFontInfo::style() const */ int QFontInfo::weight() const { - QFontEngine *engine = d->engineForScript(QUnicodeTables::Common); + QFontEngine *engine = d->engineForScript(QChar::Script_Common); Q_ASSERT(engine != 0); return engine->fontDef.weight; @@ -2515,7 +2514,7 @@ bool QFontInfo::strikeOut() const */ bool QFontInfo::fixedPitch() const { - QFontEngine *engine = d->engineForScript(QUnicodeTables::Common); + QFontEngine *engine = d->engineForScript(QChar::Script_Common); Q_ASSERT(engine != 0); #ifdef Q_OS_MAC if (!engine->fontDef.fixedPitchComputed) { @@ -2539,7 +2538,7 @@ bool QFontInfo::fixedPitch() const */ QFont::StyleHint QFontInfo::styleHint() const { - QFontEngine *engine = d->engineForScript(QUnicodeTables::Common); + QFontEngine *engine = d->engineForScript(QChar::Script_Common); Q_ASSERT(engine != 0); return (QFont::StyleHint) engine->fontDef.styleHint; } @@ -2567,7 +2566,7 @@ bool QFontInfo::rawMode() const */ bool QFontInfo::exactMatch() const { - QFontEngine *engine = d->engineForScript(QUnicodeTables::Common); + QFontEngine *engine = d->engineForScript(QChar::Script_Common); Q_ASSERT(engine != 0); return (d->rawMode ? engine->type() != QFontEngine::Box @@ -2675,7 +2674,7 @@ void QFontCache::clear() end = engineDataCache.end(); while (it != end) { QFontEngineData *data = it.value(); - for (int i = 0; i < QUnicodeTables::ScriptCount; ++i) { + for (int i = 0; i < QChar::ScriptCount; ++i) { if (data->engines[i]) { data->engines[i]->ref.deref(); data->engines[i] = 0; diff --git a/src/gui/text/qfont_p.h b/src/gui/text/qfont_p.h index b5e753e246..a35896e763 100644 --- a/src/gui/text/qfont_p.h +++ b/src/gui/text/qfont_p.h @@ -57,7 +57,6 @@ #include "QtCore/qmap.h" #include "QtCore/qobject.h" #include "QtCore/qstringlist.h" -#include <private/qunicodetables_p.h> #include <QtGui/qfontdatabase.h> #include "private/qfixed_p.h" @@ -143,7 +142,7 @@ public: QAtomicInt ref; QFontCache *fontCache; - QFontEngine *engines[QUnicodeTables::ScriptCount]; + QFontEngine *engines[QChar::ScriptCount]; }; diff --git a/src/gui/text/qfont_qpa.cpp b/src/gui/text/qfont_qpa.cpp index a955f5446d..be432dc52f 100644 --- a/src/gui/text/qfont_qpa.cpp +++ b/src/gui/text/qfont_qpa.cpp @@ -72,7 +72,7 @@ QString QFont::defaultFamily() const { QPlatformFontDatabase *fontDB = QGuiApplicationPrivate::platformIntegration()->fontDatabase(); const QStringList fallbacks = fontDB->fallbacksForFamily(QString(), QFont::StyleNormal - , QFont::StyleHint(d->request.styleHint), QUnicodeTables::Common); + , QFont::StyleHint(d->request.styleHint), QChar::Script_Common); if (!fallbacks.isEmpty()) return fallbacks.first(); return QString(); diff --git a/src/gui/text/qfontdatabase.cpp b/src/gui/text/qfontdatabase.cpp index 5b728403cb..f937e7a820 100644 --- a/src/gui/text/qfontdatabase.cpp +++ b/src/gui/text/qfontdatabase.cpp @@ -48,7 +48,6 @@ #include "qmutex.h" #include "qfile.h" #include "qfileinfo.h" -#include "private/qunicodetables_p.h" #include "qfontengine_p.h" #include <qpa/qplatformintegration.h> @@ -601,48 +600,48 @@ QtFontFamily *QFontDatabasePrivate::family(const QString &f, bool create) static const int scriptForWritingSystem[] = { - QUnicodeTables::Common, // Any - QUnicodeTables::Latin, // Latin - QUnicodeTables::Greek, // Greek - QUnicodeTables::Cyrillic, // Cyrillic - QUnicodeTables::Armenian, // Armenian - QUnicodeTables::Hebrew, // Hebrew - QUnicodeTables::Arabic, // Arabic - QUnicodeTables::Syriac, // Syriac - QUnicodeTables::Thaana, // Thaana - QUnicodeTables::Devanagari, // Devanagari - QUnicodeTables::Bengali, // Bengali - QUnicodeTables::Gurmukhi, // Gurmukhi - QUnicodeTables::Gujarati, // Gujarati - QUnicodeTables::Oriya, // Oriya - QUnicodeTables::Tamil, // Tamil - QUnicodeTables::Telugu, // Telugu - QUnicodeTables::Kannada, // Kannada - QUnicodeTables::Malayalam, // Malayalam - QUnicodeTables::Sinhala, // Sinhala - QUnicodeTables::Thai, // Thai - QUnicodeTables::Lao, // Lao - QUnicodeTables::Tibetan, // Tibetan - QUnicodeTables::Myanmar, // Myanmar - QUnicodeTables::Georgian, // Georgian - QUnicodeTables::Khmer, // Khmer - QUnicodeTables::Common, // SimplifiedChinese - QUnicodeTables::Common, // TraditionalChinese - QUnicodeTables::Common, // Japanese - QUnicodeTables::Hangul, // Korean - QUnicodeTables::Common, // Vietnamese - QUnicodeTables::Common, // Yi - QUnicodeTables::Common, // Tagalog - QUnicodeTables::Common, // Hanunoo - QUnicodeTables::Common, // Buhid - QUnicodeTables::Common, // Tagbanwa - QUnicodeTables::Common, // Limbu - QUnicodeTables::Common, // TaiLe - QUnicodeTables::Common, // Braille - QUnicodeTables::Common, // Symbol - QUnicodeTables::Ogham, // Ogham - QUnicodeTables::Runic, // Runic - QUnicodeTables::Nko // Nko + QChar::Script_Common, // Any + QChar::Script_Latin, // Latin + QChar::Script_Greek, // Greek + QChar::Script_Cyrillic, // Cyrillic + QChar::Script_Armenian, // Armenian + QChar::Script_Hebrew, // Hebrew + QChar::Script_Arabic, // Arabic + QChar::Script_Syriac, // Syriac + QChar::Script_Thaana, // Thaana + QChar::Script_Devanagari, // Devanagari + QChar::Script_Bengali, // Bengali + QChar::Script_Gurmukhi, // Gurmukhi + QChar::Script_Gujarati, // Gujarati + QChar::Script_Oriya, // Oriya + QChar::Script_Tamil, // Tamil + QChar::Script_Telugu, // Telugu + QChar::Script_Kannada, // Kannada + QChar::Script_Malayalam, // Malayalam + QChar::Script_Sinhala, // Sinhala + QChar::Script_Thai, // Thai + QChar::Script_Lao, // Lao + QChar::Script_Tibetan, // Tibetan + QChar::Script_Myanmar, // Myanmar + QChar::Script_Georgian, // Georgian + QChar::Script_Khmer, // Khmer + QChar::Script_Han, // SimplifiedChinese + QChar::Script_Han, // TraditionalChinese + QChar::Script_Han, // Japanese + QChar::Script_Hangul, // Korean + QChar::Script_Latin, // Vietnamese + QChar::Script_Yi, // Yi + QChar::Script_Tagalog, // Tagalog + QChar::Script_Hanunoo, // Hanunoo + QChar::Script_Buhid, // Buhid + QChar::Script_Tagbanwa, // Tagbanwa + QChar::Script_Limbu, // Limbu + QChar::Script_TaiLe, // TaiLe + QChar::Script_Braille, // Braille + QChar::Script_Common, // Symbol + QChar::Script_Ogham, // Ogham + QChar::Script_Runic, // Runic + QChar::Script_Nko // Nko }; int qt_script_for_writing_system(QFontDatabase::WritingSystem writingSystem) @@ -1059,7 +1058,7 @@ static void match(int script, const QFontDef &request, uint score_adjust = 0; - bool supported = (script == QUnicodeTables::Common); + bool supported = (script == QChar::Script_Common); for (int ws = 1; !supported && ws < QFontDatabase::WritingSystemsCount; ++ws) { if (scriptForWritingSystem[ws] != script) continue; diff --git a/src/gui/text/qfontdatabase_qpa.cpp b/src/gui/text/qfontdatabase_qpa.cpp index a72b21ede3..0d38c6a290 100644 --- a/src/gui/text/qfontdatabase_qpa.cpp +++ b/src/gui/text/qfontdatabase_qpa.cpp @@ -104,7 +104,7 @@ Q_GUI_EXPORT void qt_registerAliasToFontFamily(const QString &familyName, const f->aliases.push_back(alias); } -static QStringList fallbackFamilies(const QString &family, const QFont::Style &style, const QFont::StyleHint &styleHint, const QUnicodeTables::Script &script) +static QStringList fallbackFamilies(const QString &family, QFont::Style style, QFont::StyleHint styleHint, QChar::Script script) { QStringList retList = QGuiApplicationPrivate::platformIntegration()->fontDatabase()->fallbacksForFamily(family,style,styleHint,script); QFontDatabasePrivate *db = privateDb(); @@ -175,7 +175,7 @@ QFontEngine *loadSingleEngine(int script, QFontCache::Key key(def,script); QFontEngine *engine = QFontCache::instance()->findEngine(key); if (!engine) { - engine = pfdb->fontEngine(def,QUnicodeTables::Script(script),size->handle); + engine = pfdb->fontEngine(def, QChar::Script(script), size->handle); if (engine) { QFontCache::Key key(def,script); QFontCache::instance()->instance()->insertEngine(key,engine); @@ -200,7 +200,7 @@ QFontEngine *loadEngine(int script, const QFontDef &request, QFont::StyleHint styleHint = QFont::StyleHint(request.styleHint); if (styleHint == QFont::AnyStyle && request.fixedPitch) styleHint = QFont::TypeWriter; - family->fallbackFamilies = fallbackFamilies(family->name,fontStyle,styleHint,QUnicodeTables::Script(script)); + family->fallbackFamilies = fallbackFamilies(family->name, fontStyle, styleHint, QChar::Script(script)); family->askedForFallback = true; } @@ -210,7 +210,7 @@ QFontEngine *loadEngine(int script, const QFontDef &request, fallbacks = family->fallbackFamilies; QPlatformFontDatabase *pfdb = QGuiApplicationPrivate::platformIntegration()->fontDatabase(); - QFontEngineMulti *pfMultiEngine = pfdb->fontEngineMulti(engine, QUnicodeTables::Script(script)); + QFontEngineMulti *pfMultiEngine = pfdb->fontEngineMulti(engine, QChar::Script(script)); pfMultiEngine->setFallbackFamiliesList(fallbacks); engine = pfMultiEngine; @@ -322,7 +322,7 @@ QFontDatabase::findFont(int script, const QFontPrivate *fp, + fallbackFamilies(request.family, QFont::Style(request.style), QFont::StyleHint(request.styleHint), - QUnicodeTables::Script(script)); + QChar::Script(script)); for (int i = 0; !engine && i < fallbacks.size(); i++) { QFontDef def = request; @@ -427,7 +427,7 @@ void QFontDatabase::load(const QFontPrivate *d, int script) } if (fe->symbol || (d->request.styleStrategy & QFont::NoFontMerging)) { - for (int i = 0; i < QUnicodeTables::ScriptCount; ++i) { + for (int i = 0; i < QChar::ScriptCount; ++i) { if (!d->engineData->engines[i]) { d->engineData->engines[i] = fe; fe->ref.ref(); diff --git a/src/gui/text/qfontengine.cpp b/src/gui/text/qfontengine.cpp index 87fa202fb4..b320dc0e66 100644 --- a/src/gui/text/qfontengine.cpp +++ b/src/gui/text/qfontengine.cpp @@ -268,9 +268,9 @@ QFixed QFontEngine::averageCharWidth() const return bb.xoff; } -bool QFontEngine::supportsTransformations(const QTransform &transform) const +bool QFontEngine::supportsTransformation(const QTransform &transform) const { - return (transform.type() >= QTransform::TxProject); + return transform.type() < QTransform::TxProject; } void QFontEngine::getGlyphPositions(const QGlyphLayout &glyphs, const QTransform &matrix, QTextItem::RenderFlags flags, diff --git a/src/gui/text/qfontengine_ft.cpp b/src/gui/text/qfontengine_ft.cpp index 07e4cae1ee..bedd5753c7 100644 --- a/src/gui/text/qfontengine_ft.cpp +++ b/src/gui/text/qfontengine_ft.cpp @@ -1570,12 +1570,15 @@ void QFontEngineFT::recalcAdvances(QGlyphLayout *glyphs, QFontEngine::ShaperFlag glyphs->advances_x[i] = design ? QFixed::fromFixed(face->glyph->linearHoriAdvance >> 10) : QFixed::fromFixed(face->glyph->metrics.horiAdvance).round(); } - if (fontDef.styleStrategy & QFont::ForceIntegerMetrics) - glyphs->advances_x[i] = glyphs->advances_x[i].round(); glyphs->advances_y[i] = 0; } if (face) unlockFace(); + + if (fontDef.styleStrategy & QFont::ForceIntegerMetrics) { + for (int i = 0; i < glyphs->numGlyphs; ++i) + glyphs->advances_x[i] = glyphs->advances_x[i].round(); + } } glyph_metrics_t QFontEngineFT::boundingBox(const QGlyphLayout &glyphs) diff --git a/src/gui/text/qfontengine_p.h b/src/gui/text/qfontengine_p.h index c2d22d9e83..854f6fbbb6 100644 --- a/src/gui/text/qfontengine_p.h +++ b/src/gui/text/qfontengine_p.h @@ -241,7 +241,7 @@ public: return canRender(utf16, utf16len); } - virtual bool supportsTransformations(const QTransform &transform) const; + virtual bool supportsTransformation(const QTransform &transform) const; virtual Type type() const = 0; diff --git a/src/gui/text/qfontengine_qpa.cpp b/src/gui/text/qfontengine_qpa.cpp index b083e20428..f27a309d64 100644 --- a/src/gui/text/qfontengine_qpa.cpp +++ b/src/gui/text/qfontengine_qpa.cpp @@ -710,7 +710,7 @@ void QFontEngineMultiQPA::ensureFallbackFamiliesQueried() if (fallbacksQueried) return; QStringList fallbacks = QGuiApplicationPrivate::instance()->platformIntegration()->fontDatabase()->fallbacksForFamily(engine(0)->fontDef.family, QFont::Style(engine(0)->fontDef.style) - , QFont::AnyStyle, QUnicodeTables::Script(script)); + , QFont::AnyStyle, QChar::Script(script)); setFallbackFamiliesList(fallbacks); } @@ -762,7 +762,7 @@ QFontEngine* QFontEngineMultiQPA::createMultiFontEngine(QFontEngine *fe, int scr it++; } if (!engine) { - engine = QGuiApplicationPrivate::instance()->platformIntegration()->fontDatabase()->fontEngineMulti(fe, QUnicodeTables::Script(script)); + engine = QGuiApplicationPrivate::instance()->platformIntegration()->fontDatabase()->fontEngineMulti(fe, QChar::Script(script)); QFontCache::instance()->insertEngine(key, engine, /* insertMulti */ !faceIsLocal); } Q_ASSERT(engine); diff --git a/src/gui/text/qfontengine_qpf.cpp b/src/gui/text/qfontengine_qpf.cpp index df80e9e87d..2959ae666d 100644 --- a/src/gui/text/qfontengine_qpf.cpp +++ b/src/gui/text/qfontengine_qpf.cpp @@ -666,9 +666,7 @@ void QFontEngineQPF::draw(QPaintEngine *p, qreal _x, qreal _y, const QTextItemIn void QFontEngineQPF::addOutlineToPath(qreal x, qreal y, const QGlyphLayout &glyphs, QPainterPath *path, QTextItem::RenderFlags flags) { - if (renderingFontEngine && - (renderingFontEngine->type() != QFontEngine::Proxy - || static_cast<QProxyFontEngine *>(renderingFontEngine)->capabilities() & QAbstractFontEngine::CanOutlineGlyphs)) { + if (renderingFontEngine && renderingFontEngine->type() != QFontEngine::Proxy) { renderingFontEngine->addOutlineToPath(x, y, glyphs, path, flags); return; } diff --git a/src/gui/text/qfontengineglyphcache_p.h b/src/gui/text/qfontengineglyphcache_p.h index 1dc4db00c4..ac01c78399 100644 --- a/src/gui/text/qfontengineglyphcache_p.h +++ b/src/gui/text/qfontengineglyphcache_p.h @@ -78,6 +78,7 @@ public: virtual ~QFontEngineGlyphCache() { } Type cacheType() const { return m_type; } + const QTransform &transform() const { return m_transform; } QTransform m_transform; QFontEngineGlyphCache::Type m_type; diff --git a/src/gui/text/qfontmetrics.cpp b/src/gui/text/qfontmetrics.cpp index f3151da16b..d889fa97b5 100644 --- a/src/gui/text/qfontmetrics.cpp +++ b/src/gui/text/qfontmetrics.cpp @@ -45,7 +45,6 @@ #include "qfont_p.h" #include "qfontengine_p.h" -#include <private/qunicodetables_p.h> #include <math.h> @@ -262,7 +261,7 @@ bool QFontMetrics::operator ==(const QFontMetrics &other) const */ int QFontMetrics::ascent() const { - QFontEngine *engine = d->engineForScript(QUnicodeTables::Common); + QFontEngine *engine = d->engineForScript(QChar::Script_Common); Q_ASSERT(engine != 0); return qRound(engine->ascent()); } @@ -280,7 +279,7 @@ int QFontMetrics::ascent() const */ int QFontMetrics::descent() const { - QFontEngine *engine = d->engineForScript(QUnicodeTables::Common); + QFontEngine *engine = d->engineForScript(QChar::Script_Common); Q_ASSERT(engine != 0); return qRound(engine->descent()); } @@ -295,7 +294,7 @@ int QFontMetrics::descent() const */ int QFontMetrics::height() const { - QFontEngine *engine = d->engineForScript(QUnicodeTables::Common); + QFontEngine *engine = d->engineForScript(QChar::Script_Common); Q_ASSERT(engine != 0); return qRound(engine->ascent()) + qRound(engine->descent()); } @@ -309,7 +308,7 @@ int QFontMetrics::height() const */ int QFontMetrics::leading() const { - QFontEngine *engine = d->engineForScript(QUnicodeTables::Common); + QFontEngine *engine = d->engineForScript(QChar::Script_Common); Q_ASSERT(engine != 0); return qRound(engine->leading()); } @@ -323,7 +322,7 @@ int QFontMetrics::leading() const */ int QFontMetrics::lineSpacing() const { - QFontEngine *engine = d->engineForScript(QUnicodeTables::Common); + QFontEngine *engine = d->engineForScript(QChar::Script_Common); Q_ASSERT(engine != 0); return qRound(engine->leading()) + qRound(engine->ascent()) + qRound(engine->descent()); } @@ -340,7 +339,7 @@ int QFontMetrics::lineSpacing() const */ int QFontMetrics::minLeftBearing() const { - QFontEngine *engine = d->engineForScript(QUnicodeTables::Common); + QFontEngine *engine = d->engineForScript(QChar::Script_Common); Q_ASSERT(engine != 0); return qRound(engine->minLeftBearing()); } @@ -357,7 +356,7 @@ int QFontMetrics::minLeftBearing() const */ int QFontMetrics::minRightBearing() const { - QFontEngine *engine = d->engineForScript(QUnicodeTables::Common); + QFontEngine *engine = d->engineForScript(QChar::Script_Common); Q_ASSERT(engine != 0); return qRound(engine->minRightBearing()); } @@ -367,7 +366,7 @@ int QFontMetrics::minRightBearing() const */ int QFontMetrics::maxWidth() const { - QFontEngine *engine = d->engineForScript(QUnicodeTables::Common); + QFontEngine *engine = d->engineForScript(QChar::Script_Common); Q_ASSERT(engine != 0); return qRound(engine->maxCharWidth()); } @@ -378,10 +377,10 @@ int QFontMetrics::maxWidth() const */ int QFontMetrics::xHeight() const { - QFontEngine *engine = d->engineForScript(QUnicodeTables::Common); + QFontEngine *engine = d->engineForScript(QChar::Script_Common); Q_ASSERT(engine != 0); if (d->capital == QFont::SmallCaps) - return qRound(d->smallCapsFontPrivate()->engineForScript(QUnicodeTables::Common)->ascent()); + return qRound(d->smallCapsFontPrivate()->engineForScript(QChar::Script_Common)->ascent()); return qRound(engine->xHeight()); } @@ -392,7 +391,7 @@ int QFontMetrics::xHeight() const */ int QFontMetrics::averageCharWidth() const { - QFontEngine *engine = d->engineForScript(QUnicodeTables::Common); + QFontEngine *engine = d->engineForScript(QChar::Script_Common); Q_ASSERT(engine != 0); return qRound(engine->averageCharWidth()); } @@ -403,7 +402,7 @@ int QFontMetrics::averageCharWidth() const */ bool QFontMetrics::inFont(QChar ch) const { - const int script = QUnicodeTables::script(ch); + const int script = ch.script(); QFontEngine *engine = d->engineForScript(script); Q_ASSERT(engine != 0); if (engine->type() == QFontEngine::Box) @@ -417,7 +416,7 @@ bool QFontMetrics::inFont(QChar ch) const */ bool QFontMetrics::inFontUcs4(uint ucs4) const { - const int script = QUnicodeTables::script(ucs4); + const int script = QChar::script(ucs4); QFontEngine *engine = d->engineForScript(script); Q_ASSERT(engine != 0); if (engine->type() == QFontEngine::Box) @@ -439,7 +438,7 @@ bool QFontMetrics::inFontUcs4(uint ucs4) const */ int QFontMetrics::leftBearing(QChar ch) const { - const int script = QUnicodeTables::script(ch); + const int script = ch.script(); QFontEngine *engine; if (d->capital == QFont::SmallCaps && ch.isLower()) engine = d->smallCapsFontPrivate()->engineForScript(script); @@ -474,7 +473,7 @@ int QFontMetrics::leftBearing(QChar ch) const */ int QFontMetrics::rightBearing(QChar ch) const { - const int script = QUnicodeTables::script(ch); + const int script = ch.script(); QFontEngine *engine; if (d->capital == QFont::SmallCaps && ch.isLower()) engine = d->smallCapsFontPrivate()->engineForScript(script); @@ -530,7 +529,7 @@ int QFontMetrics::width(const QString &text, int len, int flags) const // Skip harfbuzz complex shaping, only use advances int numGlyphs = len; QVarLengthGlyphLayoutArray glyphs(numGlyphs); - QFontEngine *engine = d->engineForScript(QUnicodeTables::Common); + QFontEngine *engine = d->engineForScript(QChar::Script_Common); if (!engine->stringToCMap(text.data(), len, &glyphs, &numGlyphs, 0)) { glyphs.resize(numGlyphs); if (!engine->stringToCMap(text.data(), len, &glyphs, &numGlyphs, 0)) @@ -577,7 +576,7 @@ int QFontMetrics::width(QChar ch) const if (QChar::category(ch.unicode()) == QChar::Mark_NonSpacing) return 0; - const int script = QUnicodeTables::script(ch); + const int script = ch.script(); QFontEngine *engine; if (d->capital == QFont::SmallCaps && ch.isLower()) engine = d->smallCapsFontPrivate()->engineForScript(script); @@ -607,14 +606,13 @@ int QFontMetrics::width(QChar ch) const */ int QFontMetrics::charWidth(const QString &text, int pos) const { + int width = 0; if (pos < 0 || pos > (int)text.length()) - return 0; - - QChar ch = text.unicode()[pos]; - const int script = QUnicodeTables::script(ch); - int width; + return width; - if (script != QUnicodeTables::Common) { + QChar ch = text.at(pos); + const int script = ch.script(); + if (script != QChar::Script_Common) { // complex script shaping. Have to do some hard work int from = qMax(0, pos - 8); int to = qMin(text.length(), pos + 8); @@ -623,9 +621,7 @@ int QFontMetrics::charWidth(const QString &text, int pos) const layout.ignoreBidi = true; layout.itemize(); width = qRound(layout.width(pos-from, 1)); - } else if (QChar::category(ch.unicode()) == QChar::Mark_NonSpacing) { - width = 0; - } else { + } else if (ch.category() != QChar::Mark_NonSpacing) { QFontEngine *engine; if (d->capital == QFont::SmallCaps && ch.isLower()) engine = d->smallCapsFontPrivate()->engineForScript(script); @@ -694,7 +690,7 @@ QRect QFontMetrics::boundingRect(const QString &text) const */ QRect QFontMetrics::boundingRect(QChar ch) const { - const int script = QUnicodeTables::script(ch); + const int script = ch.script(); QFontEngine *engine; if (d->capital == QFont::SmallCaps && ch.isLower()) engine = d->smallCapsFontPrivate()->engineForScript(script); @@ -895,7 +891,7 @@ QString QFontMetrics::elidedText(const QString &text, Qt::TextElideMode mode, in */ int QFontMetrics::underlinePos() const { - QFontEngine *engine = d->engineForScript(QUnicodeTables::Common); + QFontEngine *engine = d->engineForScript(QChar::Script_Common); Q_ASSERT(engine != 0); return qRound(engine->underlinePosition()); } @@ -931,7 +927,7 @@ int QFontMetrics::strikeOutPos() const */ int QFontMetrics::lineWidth() const { - QFontEngine *engine = d->engineForScript(QUnicodeTables::Common); + QFontEngine *engine = d->engineForScript(QChar::Script_Common); Q_ASSERT(engine != 0); return qRound(engine->lineThickness()); } @@ -1129,7 +1125,7 @@ bool QFontMetricsF::operator ==(const QFontMetricsF &other) const */ qreal QFontMetricsF::ascent() const { - QFontEngine *engine = d->engineForScript(QUnicodeTables::Common); + QFontEngine *engine = d->engineForScript(QChar::Script_Common); Q_ASSERT(engine != 0); return engine->ascent().toReal(); } @@ -1148,7 +1144,7 @@ qreal QFontMetricsF::ascent() const */ qreal QFontMetricsF::descent() const { - QFontEngine *engine = d->engineForScript(QUnicodeTables::Common); + QFontEngine *engine = d->engineForScript(QChar::Script_Common); Q_ASSERT(engine != 0); return engine->descent().toReal(); } @@ -1163,7 +1159,7 @@ qreal QFontMetricsF::descent() const */ qreal QFontMetricsF::height() const { - QFontEngine *engine = d->engineForScript(QUnicodeTables::Common); + QFontEngine *engine = d->engineForScript(QChar::Script_Common); Q_ASSERT(engine != 0); return (engine->ascent() + engine->descent()).toReal(); @@ -1178,7 +1174,7 @@ qreal QFontMetricsF::height() const */ qreal QFontMetricsF::leading() const { - QFontEngine *engine = d->engineForScript(QUnicodeTables::Common); + QFontEngine *engine = d->engineForScript(QChar::Script_Common); Q_ASSERT(engine != 0); return engine->leading().toReal(); } @@ -1192,7 +1188,7 @@ qreal QFontMetricsF::leading() const */ qreal QFontMetricsF::lineSpacing() const { - QFontEngine *engine = d->engineForScript(QUnicodeTables::Common); + QFontEngine *engine = d->engineForScript(QChar::Script_Common); Q_ASSERT(engine != 0); return (engine->leading() + engine->ascent() + engine->descent()).toReal(); } @@ -1209,7 +1205,7 @@ qreal QFontMetricsF::lineSpacing() const */ qreal QFontMetricsF::minLeftBearing() const { - QFontEngine *engine = d->engineForScript(QUnicodeTables::Common); + QFontEngine *engine = d->engineForScript(QChar::Script_Common); Q_ASSERT(engine != 0); return engine->minLeftBearing(); } @@ -1226,7 +1222,7 @@ qreal QFontMetricsF::minLeftBearing() const */ qreal QFontMetricsF::minRightBearing() const { - QFontEngine *engine = d->engineForScript(QUnicodeTables::Common); + QFontEngine *engine = d->engineForScript(QChar::Script_Common); Q_ASSERT(engine != 0); return engine->minRightBearing(); } @@ -1236,7 +1232,7 @@ qreal QFontMetricsF::minRightBearing() const */ qreal QFontMetricsF::maxWidth() const { - QFontEngine *engine = d->engineForScript(QUnicodeTables::Common); + QFontEngine *engine = d->engineForScript(QChar::Script_Common); Q_ASSERT(engine != 0); return engine->maxCharWidth(); } @@ -1247,10 +1243,10 @@ qreal QFontMetricsF::maxWidth() const */ qreal QFontMetricsF::xHeight() const { - QFontEngine *engine = d->engineForScript(QUnicodeTables::Common); + QFontEngine *engine = d->engineForScript(QChar::Script_Common); Q_ASSERT(engine != 0); if (d->capital == QFont::SmallCaps) - return d->smallCapsFontPrivate()->engineForScript(QUnicodeTables::Common)->ascent().toReal(); + return d->smallCapsFontPrivate()->engineForScript(QChar::Script_Common)->ascent().toReal(); return engine->xHeight().toReal(); } @@ -1261,7 +1257,7 @@ qreal QFontMetricsF::xHeight() const */ qreal QFontMetricsF::averageCharWidth() const { - QFontEngine *engine = d->engineForScript(QUnicodeTables::Common); + QFontEngine *engine = d->engineForScript(QChar::Script_Common); Q_ASSERT(engine != 0); return engine->averageCharWidth().toReal(); } @@ -1272,7 +1268,7 @@ qreal QFontMetricsF::averageCharWidth() const */ bool QFontMetricsF::inFont(QChar ch) const { - const int script = QUnicodeTables::script(ch); + const int script = ch.script(); QFontEngine *engine = d->engineForScript(script); Q_ASSERT(engine != 0); if (engine->type() == QFontEngine::Box) @@ -1288,7 +1284,7 @@ bool QFontMetricsF::inFont(QChar ch) const */ bool QFontMetricsF::inFontUcs4(uint ucs4) const { - const int script = QUnicodeTables::script(ucs4); + const int script = QChar::script(ucs4); QFontEngine *engine = d->engineForScript(script); Q_ASSERT(engine != 0); if (engine->type() == QFontEngine::Box) @@ -1310,7 +1306,7 @@ bool QFontMetricsF::inFontUcs4(uint ucs4) const */ qreal QFontMetricsF::leftBearing(QChar ch) const { - const int script = QUnicodeTables::script(ch); + const int script = ch.script(); QFontEngine *engine; if (d->capital == QFont::SmallCaps && ch.isLower()) engine = d->smallCapsFontPrivate()->engineForScript(script); @@ -1345,7 +1341,7 @@ qreal QFontMetricsF::leftBearing(QChar ch) const */ qreal QFontMetricsF::rightBearing(QChar ch) const { - const int script = QUnicodeTables::script(ch); + const int script = ch.script(); QFontEngine *engine; if (d->capital == QFont::SmallCaps && ch.isLower()) engine = d->smallCapsFontPrivate()->engineForScript(script); @@ -1414,10 +1410,10 @@ qreal QFontMetricsF::width(const QString &text) const */ qreal QFontMetricsF::width(QChar ch) const { - if (QChar::category(ch.unicode()) == QChar::Mark_NonSpacing) + if (ch.category() == QChar::Mark_NonSpacing) return 0.; - const int script = QUnicodeTables::script(ch); + const int script = ch.script(); QFontEngine *engine; if (d->capital == QFont::SmallCaps && ch.isLower()) engine = d->smallCapsFontPrivate()->engineForScript(script); @@ -1482,7 +1478,7 @@ QRectF QFontMetricsF::boundingRect(const QString &text) const */ QRectF QFontMetricsF::boundingRect(QChar ch) const { - const int script = QUnicodeTables::script(ch); + const int script = ch.script(); QFontEngine *engine; if (d->capital == QFont::SmallCaps && ch.isLower()) engine = d->smallCapsFontPrivate()->engineForScript(script); @@ -1682,7 +1678,7 @@ QString QFontMetricsF::elidedText(const QString &text, Qt::TextElideMode mode, q */ qreal QFontMetricsF::underlinePos() const { - QFontEngine *engine = d->engineForScript(QUnicodeTables::Common); + QFontEngine *engine = d->engineForScript(QChar::Script_Common); Q_ASSERT(engine != 0); return engine->underlinePosition().toReal(); } @@ -1717,7 +1713,7 @@ qreal QFontMetricsF::strikeOutPos() const */ qreal QFontMetricsF::lineWidth() const { - QFontEngine *engine = d->engineForScript(QUnicodeTables::Common); + QFontEngine *engine = d->engineForScript(QChar::Script_Common); Q_ASSERT(engine != 0); return engine->lineThickness().toReal(); } diff --git a/src/gui/text/qplatformfontdatabase.cpp b/src/gui/text/qplatformfontdatabase.cpp index 070550730d..08e697cacf 100644 --- a/src/gui/text/qplatformfontdatabase.cpp +++ b/src/gui/text/qplatformfontdatabase.cpp @@ -278,8 +278,7 @@ void QPlatformFontDatabase::populateFontDatabase() option to fall back to the fonts given by \a fallbacks if \a fontEngine does not support a certain character. */ -QFontEngineMulti *QPlatformFontDatabase::fontEngineMulti(QFontEngine *fontEngine, - QUnicodeTables::Script script) +QFontEngineMulti *QPlatformFontDatabase::fontEngineMulti(QFontEngine *fontEngine, QChar::Script script) { return new QFontEngineMultiQPA(fontEngine, script); } @@ -288,7 +287,7 @@ QFontEngineMulti *QPlatformFontDatabase::fontEngineMulti(QFontEngine *fontEngine Returns the font engine that can be used to render the font described by the font definition, \a fontDef, in the specified \a script. */ -QFontEngine *QPlatformFontDatabase::fontEngine(const QFontDef &fontDef, QUnicodeTables::Script script, void *handle) +QFontEngine *QPlatformFontDatabase::fontEngine(const QFontDef &fontDef, QChar::Script script, void *handle) { Q_UNUSED(script); Q_UNUSED(handle); @@ -312,7 +311,7 @@ QFontEngine *QPlatformFontDatabase::fontEngine(const QByteArray &fontData, qreal Returns a list of alternative fonts for the specified \a family and \a style and \a script using the \a styleHint given. */ -QStringList QPlatformFontDatabase::fallbacksForFamily(const QString family, const QFont::Style &style, const QFont::StyleHint &styleHint, const QUnicodeTables::Script &script) const +QStringList QPlatformFontDatabase::fallbacksForFamily(const QString &family, QFont::Style style, QFont::StyleHint styleHint, QChar::Script script) const { Q_UNUSED(family); Q_UNUSED(style); diff --git a/src/gui/text/qplatformfontdatabase.h b/src/gui/text/qplatformfontdatabase.h index 319447c19f..0c876505fb 100644 --- a/src/gui/text/qplatformfontdatabase.h +++ b/src/gui/text/qplatformfontdatabase.h @@ -98,9 +98,9 @@ class Q_GUI_EXPORT QPlatformFontDatabase public: virtual ~QPlatformFontDatabase(); virtual void populateFontDatabase(); - virtual QFontEngineMulti *fontEngineMulti(QFontEngine *fontEngine, QUnicodeTables::Script script); - virtual QFontEngine *fontEngine(const QFontDef &fontDef, QUnicodeTables::Script script, void *handle); - virtual QStringList fallbacksForFamily(const QString family, const QFont::Style &style, const QFont::StyleHint &styleHint, const QUnicodeTables::Script &script) const; + virtual QFontEngineMulti *fontEngineMulti(QFontEngine *fontEngine, QChar::Script script); + virtual QFontEngine *fontEngine(const QFontDef &fontDef, QChar::Script script, void *handle); + virtual QStringList fallbacksForFamily(const QString &family, QFont::Style style, QFont::StyleHint styleHint, QChar::Script script) const; virtual QStringList addApplicationFont(const QByteArray &fontData, const QString &fileName); virtual void releaseHandle(void *handle); diff --git a/src/gui/text/qrawfont_ft.cpp b/src/gui/text/qrawfont_ft.cpp deleted file mode 100644 index 5cac45b216..0000000000 --- a/src/gui/text/qrawfont_ft.cpp +++ /dev/null @@ -1,129 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/legal -** -** This file is part of the QtGui module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and Digia. For licensing terms and -** conditions see http://qt.digia.com/licensing. For further information -** use the contact form at http://qt.digia.com/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Digia gives you certain additional -** rights. These rights are described in the Digia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include <QtCore/qglobal.h> - -#if !defined(QT_NO_RAWFONT) - -#include "qrawfont_p.h" -#include "qfontengine_ft_p.h" -#include "quuid.h" - - -QT_BEGIN_NAMESPACE - -class QFontEngineFTRawFont - - : public QFontEngineFT - -{ -public: - QFontEngineFTRawFont(const QFontDef &fontDef) - : QFontEngineFT(fontDef) - { - } - - void updateFamilyNameAndStyle() - { - fontDef.family = QString::fromUtf8(freetype->face->family_name); - - if (freetype->face->style_flags & FT_STYLE_FLAG_ITALIC) - fontDef.style = QFont::StyleItalic; - - if (freetype->face->style_flags & FT_STYLE_FLAG_BOLD) - fontDef.weight = QFont::Bold; - } - - bool initFromData(const QByteArray &fontData) - { - FaceId faceId; - faceId.filename = ""; - faceId.index = 0; - faceId.uuid = QUuid::createUuid().toByteArray(); - - return init(faceId, true, Format_None, fontData); - } -}; - - -void QRawFontPrivate::platformCleanUp() -{ - // Font engine handles all resources -} - -void QRawFontPrivate::platformLoadFromData(const QByteArray &fontData, qreal pixelSize, - QFont::HintingPreference hintingPreference) -{ - Q_ASSERT(fontEngine == 0); - - QFontDef fontDef; - fontDef.pixelSize = pixelSize; - - QFontEngineFTRawFont *fe = new QFontEngineFTRawFont(fontDef); - if (!fe->initFromData(fontData)) { - delete fe; - return; - } - - fe->updateFamilyNameAndStyle(); - - switch (hintingPreference) { - case QFont::PreferNoHinting: - fe->setDefaultHintStyle(QFontEngineFT::HintNone); - break; - case QFont::PreferFullHinting: - fe->setDefaultHintStyle(QFontEngineFT::HintFull); - break; - case QFont::PreferVerticalHinting: - fe->setDefaultHintStyle(QFontEngineFT::HintLight); - break; - default: - // Leave it as it is - break; - } - - fontEngine = fe; - fontEngine->ref.ref(); -} - -QT_END_NAMESPACE - -#endif // QT_NO_RAWFONT diff --git a/src/gui/text/qtextengine.cpp b/src/gui/text/qtextengine.cpp index f0776c6098..e51e0c0835 100644 --- a/src/gui/text/qtextengine.cpp +++ b/src/gui/text/qtextengine.cpp @@ -51,7 +51,6 @@ #include "qfont_p.h" #include "qfontengine_p.h" #include "qstring.h" -#include <private/qunicodetables_p.h> #include "qtextdocument_p.h" #include "qrawfont.h" #include "qrawfont_p.h" @@ -134,7 +133,7 @@ private: // along, and nothing else. if (m_analysis[i].bidiLevel == m_analysis[start].bidiLevel && m_analysis[i].flags == m_analysis[start].flags - && (m_analysis[i].script == m_analysis[start].script || m_string[i] == QLatin1Char('.')) + && (script_to_hbscript(m_analysis[i].script) == script_to_hbscript(m_analysis[start].script) || m_string[i] == QLatin1Char('.')) && m_analysis[i].flags < QScriptAnalysis::SpaceTabOrObject && i - start < MaxItemLength) continue; @@ -1004,7 +1003,7 @@ void QTextEngine::shapeTextWithHarfbuzz(int item) const memset(&entire_shaper_item, 0, sizeof(entire_shaper_item)); entire_shaper_item.string = reinterpret_cast<const HB_UChar16 *>(layoutData->string.constData()); entire_shaper_item.stringLength = layoutData->string.length(); - entire_shaper_item.item.script = (HB_Script)si.analysis.script; + entire_shaper_item.item.script = script_to_hbscript(si.analysis.script); entire_shaper_item.item.pos = si.position; entire_shaper_item.item.length = length(item); entire_shaper_item.item.bidiLevel = si.analysis.bidiLevel; @@ -1348,42 +1347,44 @@ void QTextEngine::itemize() const const ushort *uc = reinterpret_cast<const ushort *>(layoutData->string.unicode()); const ushort *e = uc + length; - int lastScript = QUnicodeTables::Common; + uchar lastScript = QChar::Script_Common; while (uc < e) { switch (*uc) { case QChar::ObjectReplacementCharacter: - analysis->script = QUnicodeTables::Common; + analysis->script = QChar::Script_Common; analysis->flags = QScriptAnalysis::Object; break; case QChar::LineSeparator: if (analysis->bidiLevel % 2) --analysis->bidiLevel; - analysis->script = QUnicodeTables::Common; + analysis->script = QChar::Script_Common; analysis->flags = QScriptAnalysis::LineOrParagraphSeparator; if (option.flags() & QTextOption::ShowLineAndParagraphSeparators) *const_cast<ushort*>(uc) = 0x21B5; // visual line separator break; case QChar::Tabulation: - analysis->script = QUnicodeTables::Common; + analysis->script = QChar::Script_Common; analysis->flags = QScriptAnalysis::Tab; analysis->bidiLevel = control.baseLevel(); break; case QChar::Space: case QChar::Nbsp: if (option.flags() & QTextOption::ShowTabsAndSpaces) { - analysis->script = QUnicodeTables::Common; + analysis->script = QChar::Script_Common; analysis->flags = QScriptAnalysis::Space; analysis->bidiLevel = control.baseLevel(); break; } // fall through default: - int script = QUnicodeTables::script(*uc); - analysis->script = script == QUnicodeTables::Inherited ? lastScript : script; + analysis->script = QChar::script(*uc); + if (analysis->script == QChar::Script_Inherited) + analysis->script = lastScript; analysis->flags = QScriptAnalysis::None; break; } lastScript = analysis->script; + analysis->script = hbscript_to_script(script_to_hbscript(analysis->script)); // retain the old behavior ++uc; ++analysis; } @@ -2035,9 +2036,9 @@ void QScriptLine::setDefaultHeight(QTextEngine *eng) QPaintDevice *pdev = eng->block.docHandle()->layout()->paintDevice(); if (pdev) f = QFont(f, pdev); - e = f.d->engineForScript(QUnicodeTables::Common); + e = f.d->engineForScript(QChar::Script_Common); } else { - e = eng->fnt.d->engineForScript(QUnicodeTables::Common); + e = eng->fnt.d->engineForScript(QChar::Script_Common); } QFixed other_ascent = e->ascent(); @@ -2421,7 +2422,7 @@ QString QTextEngine::elidedText(Qt::TextElideMode mode, const QFixed &width, int { QChar ellipsisChar(0x2026); - QFontEngine *fe = fnt.d->engineForScript(QUnicodeTables::Common); + QFontEngine *fe = fnt.d->engineForScript(QChar::Script_Common); QGlyphLayoutArray<1> ellipsisGlyph; { @@ -2868,8 +2869,8 @@ int QTextEngine::positionInLigature(const QScriptItem *si, int end, int clusterStart = -1; int clusterLength = 0; - if (si->analysis.script != QUnicodeTables::Common && - si->analysis.script != QUnicodeTables::Greek) { + if (si->analysis.script != QChar::Script_Common && + si->analysis.script != QChar::Script_Greek) { if (glyph_pos == -1) return si->position + end; else { diff --git a/src/gui/util/qvalidator.cpp b/src/gui/util/qvalidator.cpp index b94ec7f1bb..ed3b3b6dd6 100644 --- a/src/gui/util/qvalidator.cpp +++ b/src/gui/util/qvalidator.cpp @@ -1,6 +1,7 @@ /**************************************************************************** ** ** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Copyright (C) 2012 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com, author Giuseppe D'Angelo <giuseppe.dangelo@kdab.com> ** Contact: http://www.qt-project.org/legal ** ** This file is part of the QtGui module of the Qt Toolkit. @@ -501,9 +502,6 @@ void QIntValidator::setTop(int top) setRange(bottom(), top); } - -#ifndef QT_NO_REGEXP - /*! \internal */ @@ -520,6 +518,8 @@ QValidator::QValidator(QValidatorPrivate &d, QObject *parent) { } +#ifndef QT_NO_REGEXP + class QDoubleValidatorPrivate : public QValidatorPrivate { Q_DECLARE_PUBLIC(QDoubleValidator) @@ -906,6 +906,159 @@ void QRegExpValidator::setRegExp(const QRegExp& rx) #endif +#ifndef QT_NO_REGULAREXPRESSION + +/*! + \class QRegularExpressionValidator + \brief The QRegularExpressionValidator class is used to check a string + against a regular expression. + + \since 5.1 + + QRegularExpressionValidator uses a regular expression (regexp) to + determine whether an input string is \l Acceptable, \l + Intermediate, or \l Invalid. The regexp can either be supplied + when the QRegularExpressionValidator is constructed, or at a later time. + + If the regexp partially matches against the string, the result is + considered \l Intermediate. For example, "" and "A" are \l Intermediate for + the regexp \b{[A-Z][0-9]} (whereas "_" would be \l Invalid). + + QRegularExpressionValidator automatically wraps the regular expression in + the \c{\\A} and \c{\\z} anchors; in other words, it always attempts to do + an exact match. + + Example of use: + \snippet code/src_gui_util_qvalidator.cpp 5 + + Below we present some examples of validators. In practice they would + normally be associated with a widget as in the example above. + + \snippet code/src_gui_util_qvalidator.cpp 6 + + \sa QRegularExpression, QIntValidator, QDoubleValidator, QRegExpValidator +*/ + +class QRegularExpressionValidatorPrivate : public QValidatorPrivate +{ + Q_DECLARE_PUBLIC(QRegularExpressionValidator) + +public: + QRegularExpression origRe; // the one set by the user + QRegularExpression usedRe; // the one actually used + void setRegularExpression(const QRegularExpression &re); +}; + +/*! + Constructs a validator with a \a parent object that accepts + any string (including an empty one) as valid. +*/ + +QRegularExpressionValidator::QRegularExpressionValidator(QObject *parent) + : QValidator(*new QRegularExpressionValidatorPrivate, parent) +{ + // origRe in the private will be an empty QRegularExpression, + // and therefore this validator will match any string. +} + +/*! + Constructs a validator with a \a parent object that + accepts all strings that match the regular expression \a re. +*/ + +QRegularExpressionValidator::QRegularExpressionValidator(const QRegularExpression &re, QObject *parent) + : QValidator(*new QRegularExpressionValidatorPrivate, parent) +{ + Q_D(QRegularExpressionValidator); + d->setRegularExpression(re); +} + + +/*! + Destroys the validator. +*/ + +QRegularExpressionValidator::~QRegularExpressionValidator() +{ +} + +/*! + Returns \l Acceptable if \a input is matched by the regular expression for + this validator, \l Intermediate if it has matched partially (i.e. could be + a valid match if additional valid characters are added), and \l Invalid if + \a input is not matched. + + In case the \a input is not matched, the \a pos parameter is set to + the length of the \a input parameter; otherwise, it is not modified. + + For example, if the regular expression is \b{\\w\\d\\d} (word-character, + digit, digit) then "A57" is \l Acceptable, "E5" is \l Intermediate, and + "+9" is \l Invalid. + + \sa QRegularExpression::match() +*/ + +QValidator::State QRegularExpressionValidator::validate(QString &input, int &pos) const +{ + Q_D(const QRegularExpressionValidator); + + // We want a validator with an empty QRegularExpression to match anything; + // since we're going to do an exact match (by using d->usedRe), first check if the rx is empty + // (and, if so, accept the input). + if (d->origRe.pattern().isEmpty()) + return Acceptable; + + const QRegularExpressionMatch m = d->usedRe.match(input, 0, QRegularExpression::PartialPreferCompleteMatch); + if (m.hasMatch()) { + return Acceptable; + } else if (m.hasPartialMatch()) { + return Intermediate; + } else { + pos = input.size(); + return Invalid; + } +} + +/*! + \property QRegularExpressionValidator::regularExpression + \brief the regular expression used for validation + + By default, this property contains a regular expression with an empty + pattern (which therefore matches any string). +*/ + +QRegularExpression QRegularExpressionValidator::regularExpression() const +{ + Q_D(const QRegularExpressionValidator); + return d->origRe; +} + +void QRegularExpressionValidator::setRegularExpression(const QRegularExpression &re) +{ + Q_D(QRegularExpressionValidator); + d->setRegularExpression(re); +} + +/*! + \internal + + Sets \a re as the regular expression. It wraps the regexp that's actually used + between \\A and \\z, therefore forcing an exact match. +*/ +void QRegularExpressionValidatorPrivate::setRegularExpression(const QRegularExpression &re) +{ + Q_Q(QRegularExpressionValidator); + + if (origRe != re) { + usedRe = origRe = re; // copies also the pattern options + usedRe.setPattern(QStringLiteral("\\A(?:") + re.pattern() + QStringLiteral(")\\z")); + emit q->regularExpressionChanged(re); + emit q->changed(); + } +} + +#endif // QT_NO_REGULAREXPRESSION + QT_END_NAMESPACE #endif // QT_NO_VALIDATOR diff --git a/src/gui/util/qvalidator.h b/src/gui/util/qvalidator.h index 6ffab4907b..8aba8ccfc3 100644 --- a/src/gui/util/qvalidator.h +++ b/src/gui/util/qvalidator.h @@ -1,6 +1,7 @@ /**************************************************************************** ** ** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Copyright (C) 2012 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com, author Giuseppe D'Angelo <giuseppe.dangelo@kdab.com> ** Contact: http://www.qt-project.org/legal ** ** This file is part of the QtGui module of the Qt Toolkit. @@ -45,6 +46,7 @@ #include <QtCore/qobject.h> #include <QtCore/qstring.h> #include <QtCore/qregexp.h> +#include <QtCore/qregularexpression.h> #include <QtCore/qlocale.h> QT_BEGIN_HEADER @@ -195,6 +197,37 @@ private: #endif // QT_NO_REGEXP +#ifndef QT_NO_REGULAREXPRESSION + +class QRegularExpressionValidatorPrivate; + +class Q_GUI_EXPORT QRegularExpressionValidator : public QValidator +{ + Q_OBJECT + Q_PROPERTY(QRegularExpression regularExpression READ regularExpression WRITE setRegularExpression NOTIFY regularExpressionChanged) + +public: + explicit QRegularExpressionValidator(QObject *parent = 0); + explicit QRegularExpressionValidator(const QRegularExpression &re, QObject *parent = 0); + ~QRegularExpressionValidator(); + + virtual QValidator::State validate(QString &input, int &pos) const Q_DECL_OVERRIDE; + + QRegularExpression regularExpression() const; + +public Q_SLOTS: + void setRegularExpression(const QRegularExpression &re); + +Q_SIGNALS: + void regularExpressionChanged(const QRegularExpression &re); + +private: + Q_DISABLE_COPY(QRegularExpressionValidator) + Q_DECLARE_PRIVATE(QRegularExpressionValidator) +}; + +#endif // QT_NO_REGULAREXPRESSION + #endif // QT_NO_VALIDATOR QT_END_NAMESPACE |