diff options
Diffstat (limited to 'src/gui')
25 files changed, 239 insertions, 138 deletions
diff --git a/src/gui/configure.json b/src/gui/configure.json index cc2f0f303b..3f139cf02d 100644 --- a/src/gui/configure.json +++ b/src/gui/configure.json @@ -9,6 +9,7 @@ "options": { "android-style-assets": "boolean", "angle": "boolean", + "direct2d": "boolean", "directfb": "boolean", "directwrite": "boolean", "egl": "boolean", @@ -455,8 +456,7 @@ }, "direct2d": { "label": "Direct 2D", - "autoDetect": false, - "condition": "config.win32 && libs.direct2d", + "condition": "config.win32 && !config.winrt && libs.direct2d", "output": [ "privateFeature" ] }, "evdev": { @@ -861,6 +861,12 @@ "condition": "features.library", "output": [ "publicFeature", "feature" ] }, + "highdpiscaling": { + "label": "High DPI Scaling", + "purpose": "Provides automatic scaling of DPI-unaware applications on high-DPI displays.", + "section": "Kernel", + "output": [ "publicFeature", "feature" ] + }, "validator": { "label": "QValidator", "purpose": "Supports validation of input text.", diff --git a/src/gui/configure.pri b/src/gui/configure.pri index ee5c7730df..aaffa835dc 100644 --- a/src/gui/configure.pri +++ b/src/gui/configure.pri @@ -12,7 +12,7 @@ defineTest(qtConfLibrary_freetype) { return(true) } } - return(false) + return(true) } # Check for Direct X SDK (include, lib, and direct shader compiler 'fxc'). diff --git a/src/gui/image/qicon.cpp b/src/gui/image/qicon.cpp index 094f44b2ab..e8f2c878c8 100644 --- a/src/gui/image/qicon.cpp +++ b/src/gui/image/qicon.cpp @@ -303,7 +303,7 @@ QPixmap QPixmapIconEngine::pixmap(const QSize &size, QIcon::Mode mode, QIcon::St QString key = QLatin1String("qt_") % HexString<quint64>(pm.cacheKey()) - % HexString<uint>(pe->mode) + % HexString<uint>(pe ? pe->mode : QIcon::Normal) % HexString<quint64>(QGuiApplication::palette().cacheKey()) % HexString<uint>(actualSize.width()) % HexString<uint>(actualSize.height()); diff --git a/src/gui/image/qiconloader.cpp b/src/gui/image/qiconloader.cpp index eda9d6f24e..324f13a17b 100644 --- a/src/gui/image/qiconloader.cpp +++ b/src/gui/image/qiconloader.cpp @@ -378,18 +378,14 @@ QThemeIconInfo QIconLoader::findIconHelper(const QString &themeName, QThemeIconInfo info; Q_ASSERT(!themeName.isEmpty()); - QPixmap pixmap; - // Used to protect against potential recursions visited << themeName; - QIconTheme theme = themeList.value(themeName); + QIconTheme &theme = themeList[themeName]; if (!theme.isValid()) { theme = QIconTheme(themeName); if (!theme.isValid()) theme = QIconTheme(fallbackTheme()); - - themeList.insert(themeName, theme); } const QStringList contentDirs = theme.contentDirs(); diff --git a/src/gui/image/qpixmapcache.cpp b/src/gui/image/qpixmapcache.cpp index 6d03332367..73448943e1 100644 --- a/src/gui/image/qpixmapcache.cpp +++ b/src/gui/image/qpixmapcache.cpp @@ -324,26 +324,23 @@ QPixmap *QPMCache::object(const QPixmapCache::Key &key) const bool QPMCache::insert(const QString& key, const QPixmap &pixmap, int cost) { - QPixmapCache::Key cacheKey; - QPixmapCache::Key oldCacheKey = cacheKeys.value(key); + QPixmapCache::Key &cacheKey = cacheKeys[key]; //If for the same key we add already a pixmap we should delete it - if (oldCacheKey.d) { - QCache<QPixmapCache::Key, QPixmapCacheEntry>::remove(oldCacheKey); - cacheKeys.remove(key); - } + if (cacheKey.d) + QCache<QPixmapCache::Key, QPixmapCacheEntry>::remove(cacheKey); //we create a new key the old one has been removed cacheKey = createKey(); bool success = QCache<QPixmapCache::Key, QPixmapCacheEntry>::insert(cacheKey, new QPixmapCacheEntry(cacheKey, pixmap), cost); if (success) { - cacheKeys.insert(key, cacheKey); if (!theid) { theid = startTimer(flush_time); t = false; } } else { //Insertion failed we released the new allocated key + cacheKeys.remove(key); releaseKey(cacheKey); } return success; @@ -389,12 +386,12 @@ bool QPMCache::replace(const QPixmapCache::Key &key, const QPixmap &pixmap, int bool QPMCache::remove(const QString &key) { - QPixmapCache::Key cacheKey = cacheKeys.value(key); + auto cacheKey = cacheKeys.constFind(key); //The key was not in the cache - if (!cacheKey.d) + if (cacheKey == cacheKeys.constEnd()) return false; - cacheKeys.remove(key); - return QCache<QPixmapCache::Key, QPixmapCacheEntry>::remove(cacheKey); + cacheKeys.erase(cacheKey); + return QCache<QPixmapCache::Key, QPixmapCacheEntry>::remove(cacheKey.value()); } bool QPMCache::remove(const QPixmapCache::Key &key) diff --git a/src/gui/kernel/kernel.pri b/src/gui/kernel/kernel.pri index 3b7e03a0ff..792ca9fbaf 100644 --- a/src/gui/kernel/kernel.pri +++ b/src/gui/kernel/kernel.pri @@ -139,7 +139,7 @@ SOURCES += \ kernel/qhighdpiscaling.cpp -qtConfig(opengl(es2)?) { +qtConfig(opengl) { HEADERS += \ kernel/qplatformopenglcontext.h \ kernel/qopenglcontext.h \ diff --git a/src/gui/kernel/qhighdpiscaling.cpp b/src/gui/kernel/qhighdpiscaling.cpp index 1085b546a7..085652879c 100644 --- a/src/gui/kernel/qhighdpiscaling.cpp +++ b/src/gui/kernel/qhighdpiscaling.cpp @@ -343,8 +343,10 @@ static const char scaleFactorProperty[] = "_q_scaleFactor"; */ void QHighDpiScaling::setScreenFactor(QScreen *screen, qreal factor) { - m_screenFactorSet = true; - m_active = true; + if (!qFuzzyCompare(factor, qreal(1))) { + m_screenFactorSet = true; + m_active = true; + } screen->setProperty(scaleFactorProperty, QVariant(factor)); // hack to force re-evaluation of screen geometry diff --git a/src/gui/kernel/qopenglcontext.cpp b/src/gui/kernel/qopenglcontext.cpp index 7e5697e5d8..8aea593bf0 100644 --- a/src/gui/kernel/qopenglcontext.cpp +++ b/src/gui/kernel/qopenglcontext.cpp @@ -848,14 +848,15 @@ QAbstractOpenGLFunctions *QOpenGLContext::versionFunctions(const QOpenGLVersionP // Create object if suitable one not cached QAbstractOpenGLFunctions* funcs = 0; - if (!d->versionFunctions.contains(vp)) { + auto it = d->versionFunctions.constFind(vp); + if (it == d->versionFunctions.constEnd()) { funcs = QOpenGLVersionFunctionsFactory::create(vp); if (funcs) { funcs->setOwningContext(this); d->versionFunctions.insert(vp, funcs); } } else { - funcs = d->versionFunctions.value(vp); + funcs = it.value(); } if (funcs && QOpenGLContext::currentContext() == this) diff --git a/src/gui/kernel/qopenglcontext_p.h b/src/gui/kernel/qopenglcontext_p.h index 57f70356b8..64bf55beee 100644 --- a/src/gui/kernel/qopenglcontext_p.h +++ b/src/gui/kernel/qopenglcontext_p.h @@ -266,7 +266,7 @@ public: static QOpenGLContextPrivate *get(QOpenGLContext *context) { - return context->d_func(); + return context ? context->d_func() : Q_NULLPTR; } #if !defined(QT_NO_DEBUG) diff --git a/src/gui/kernel/qwindow.cpp b/src/gui/kernel/qwindow.cpp index ca29906fad..124e997c58 100644 --- a/src/gui/kernel/qwindow.cpp +++ b/src/gui/kernel/qwindow.cpp @@ -2553,6 +2553,9 @@ void QWindowPrivate::_q_clearAlert() See the \l{Qt::CursorShape}{list of predefined cursor objects} for a range of useful shapes. + If no cursor has been set, or after a call to unsetCursor(), the + parent window's cursor is used. + By default, the cursor has the Qt::ArrowCursor shape. Some underlying window implementations will reset the cursor if it diff --git a/src/gui/opengl/opengl.pri b/src/gui/opengl/opengl.pri index 2c3cca6b18..712cf144e0 100644 --- a/src/gui/opengl/opengl.pri +++ b/src/gui/opengl/opengl.pri @@ -3,7 +3,7 @@ qtConfig(opengl): CONFIG += opengl qtConfig(opengles2): CONFIG += opengles2 -qtConfig(opengl(es2)?) { +qtConfig(opengl) { HEADERS += opengl/qopengl.h \ opengl/qopengl_p.h \ diff --git a/src/gui/opengl/qopengl.cpp b/src/gui/opengl/qopengl.cpp index 4f4f543ba8..e61473cb7b 100644 --- a/src/gui/opengl/qopengl.cpp +++ b/src/gui/opengl/qopengl.cpp @@ -136,9 +136,6 @@ QDebug operator<<(QDebug d, const QOpenGLConfig::Gpu &g) return d; } -enum Operator { NotEqual, LessThan, LessEqualThan, Equals, GreaterThan, GreaterEqualThan }; -static const char operators[][3] = {"!=", "<", "<=", "=", ">", ">="}; - typedef QJsonArray::ConstIterator JsonArrayConstIt; static inline bool contains(const QJsonArray &haystack, unsigned needle) @@ -160,6 +157,9 @@ static inline bool contains(const QJsonArray &haystack, const QString &needle) } namespace { +enum Operator { NotEqual, LessThan, LessEqualThan, Equals, GreaterThan, GreaterEqualThan }; +static const char operators[][3] = {"!=", "<", "<=", "=", ">", ">="}; + // VersionTerm describing a version term consisting of number and operator // found in os.version and driver_version. struct VersionTerm { diff --git a/src/gui/opengl/qopengl.h b/src/gui/opengl/qopengl.h index c7a3e79666..cd44ddfe4d 100644 --- a/src/gui/opengl/qopengl.h +++ b/src/gui/opengl/qopengl.h @@ -95,8 +95,11 @@ typedef void* GLeglImageOES; // applications cannot target ES 3. Therefore QOpenGLFunctions and // friends do everything dynamically and never rely on these macros. +// Some Khronos headers use the ext proto guard in the standard headers as well, +// which is bad. Work it around, but avoid spilling over to the ext header. # ifndef GL_GLEXT_PROTOTYPES # define GL_GLEXT_PROTOTYPES +# define QGL_TEMP_GLEXT_PROTO # endif # if defined(QT_OPENGL_ES_3_1) @@ -107,6 +110,11 @@ typedef void* GLeglImageOES; # include <GLES2/gl2.h> #endif +# ifdef QGL_TEMP_GLEXT_PROTO +# undef GL_GLEXT_PROTOTYPES +# undef QGL_TEMP_GLEXT_PROTO +# endif + /* Some GLES2 implementations (like the one on Harmattan) are missing the typedef for GLchar. Work around it here by adding it. The Kkronos headers @@ -125,7 +133,15 @@ typedef char GLchar; # include <OpenGL/glext.h> # else # define GL_GLEXT_LEGACY // Prevents GL/gl.h from #including system glext.h -# include <GL/gl.h> +// Some Khronos headers use the ext proto guard in the standard headers as well, +// which is bad. Work it around, but avoid spilling over to the ext header. +# ifndef GL_GLEXT_PROTOTYPES +# define GL_GLEXT_PROTOTYPES +# include <GL/gl.h> +# undef GL_GLEXT_PROTOTYPES +# else +# include <GL/gl.h> +# endif # include <QtGui/qopenglext.h> # endif // Q_OS_MAC #endif // QT_OPENGL_ES_2 diff --git a/src/gui/opengl/qopenglframebufferobject.cpp b/src/gui/opengl/qopenglframebufferobject.cpp index 4833617377..cedbe19191 100644 --- a/src/gui/opengl/qopenglframebufferobject.cpp +++ b/src/gui/opengl/qopenglframebufferobject.cpp @@ -950,6 +950,12 @@ QOpenGLFramebufferObject::~QOpenGLFramebufferObject() d->stencil_buffer_guard->free(); if (d->fbo_guard) d->fbo_guard->free(); + + QOpenGLContextPrivate *contextPrv = QOpenGLContextPrivate::get(QOpenGLContext::currentContext()); + if (contextPrv && contextPrv->qgl_current_fbo == this) { + contextPrv->qgl_current_fbo_invalid = true; + contextPrv->qgl_current_fbo = Q_NULLPTR; + } } /*! diff --git a/src/gui/opengl/qopenglshaderprogram.cpp b/src/gui/opengl/qopenglshaderprogram.cpp index 1ed5f7317a..b92d97c143 100644 --- a/src/gui/opengl/qopenglshaderprogram.cpp +++ b/src/gui/opengl/qopenglshaderprogram.cpp @@ -493,73 +493,84 @@ static QVersionDirectivePosition findVersionDirectivePosition(const char *source { Q_ASSERT(source); - QString working = QString::fromUtf8(source); - // According to the GLSL spec the #version directive must not be // preceded by anything but whitespace and comments. // In order to not get confused by #version directives within a - // multiline comment, we need to run a minimal preprocessor first. + // multiline comment, we need to do some minimal comment parsing + // while searching for the directive. enum { Normal, + StartOfLine, + PreprocessorDirective, CommentStarting, MultiLineComment, SingleLineComment, CommentEnding - } state = Normal; + } state = StartOfLine; - for (QChar *c = working.begin(); c != working.end(); ++c) { + const char *c = source; + while (*c) { switch (state) { + case PreprocessorDirective: + if (*c == ' ' || *c == '\t') + break; + if (!strncmp(c, "version", strlen("version"))) { + // Found version directive + c += strlen("version"); + while (*c && *c != '\n') + ++c; + int splitPosition = c - source + 1; + int linePosition = int(std::count(source, c, '\n')) + 1; + return QVersionDirectivePosition(splitPosition, linePosition); + } else if (*c == '/') + state = CommentStarting; + else if (*c == '\n') + state = StartOfLine; + else + state = Normal; + break; + case StartOfLine: + if (*c == ' ' || *c == '\t') + break; + else if (*c == '#') { + state = PreprocessorDirective; + break; + } + state = Normal; + // fall through case Normal: - if (*c == QLatin1Char('/')) + if (*c == '/') state = CommentStarting; + else if (*c == '\n') + state = StartOfLine; break; case CommentStarting: - if (*c == QLatin1Char('*')) + if (*c == '*') state = MultiLineComment; - else if (*c == QLatin1Char('/')) + else if (*c == '/') state = SingleLineComment; else state = Normal; break; case MultiLineComment: - if (*c == QLatin1Char('*')) + if (*c == '*') state = CommentEnding; - else if (*c == QLatin1Char('#')) - *c = QLatin1Char('_'); break; case SingleLineComment: - if (*c == QLatin1Char('\n')) + if (*c == '\n') state = Normal; - else if (*c == QLatin1Char('#')) - *c = QLatin1Char('_'); break; case CommentEnding: - if (*c == QLatin1Char('/')) { + if (*c == '/') state = Normal; - } else { - if (*c == QLatin1Char('#')) - *c = QLatin1Char('_'); - if (*c != QLatin1Char('*')) - state = MultiLineComment; - } + else if (*c != QLatin1Char('*')) + state = MultiLineComment; break; } + ++c; } - // Search for #version directive - int splitPosition = 0; - int linePosition = 1; - - static const QRegularExpression pattern(QStringLiteral("^\\s*#\\s*version.*(\\n)?"), - QRegularExpression::MultilineOption - | QRegularExpression::OptimizeOnFirstUsageOption); - QRegularExpressionMatch match = pattern.match(working); - if (match.hasMatch()) { - splitPosition = match.capturedEnd(); - linePosition += int(std::count(working.begin(), working.begin() + splitPosition, QLatin1Char('\n'))); - } - - return QVersionDirectivePosition(splitPosition, linePosition); + return QVersionDirectivePosition(0, 1); } /*! diff --git a/src/gui/painting/painting.pri b/src/gui/painting/painting.pri index a61865a0b6..86e35c39f8 100644 --- a/src/gui/painting/painting.pri +++ b/src/gui/painting/painting.pri @@ -65,7 +65,6 @@ SOURCES += \ painting/qcolor.cpp \ painting/qcompositionfunctions.cpp \ painting/qcosmeticstroker.cpp \ - painting/qcssutil.cpp \ painting/qdrawhelper.cpp \ painting/qemulationpaintengine.cpp \ painting/qgammatables.cpp \ @@ -104,6 +103,17 @@ darwin { SOURCES += painting/qcoregraphics.mm } +qtConfig(cssparser) { + SOURCES += \ + painting/qcssutil.cpp +} + +# Causes internal compiler errors with at least GCC 5.3.1: +gcc:equals(QT_GCC_MAJOR_VERSION, 5) { + SOURCES -= painting/qdrawhelper.cpp + NO_PCH_SOURCES += painting/qdrawhelper.cpp +} + SSE2_SOURCES += painting/qdrawhelper_sse2.cpp SSSE3_SOURCES += painting/qdrawhelper_ssse3.cpp SSE4_1_SOURCES += painting/qdrawhelper_sse4.cpp \ diff --git a/src/gui/painting/qdrawhelper.cpp b/src/gui/painting/qdrawhelper.cpp index 2716d92d13..fe1ff6603d 100644 --- a/src/gui/painting/qdrawhelper.cpp +++ b/src/gui/painting/qdrawhelper.cpp @@ -4405,8 +4405,10 @@ static void blend_tiled_argb(int count, const QSpan *spans, void *userData) uint *dest = ((uint *)data->rasterBuffer->scanLine(spans->y)) + x; op.func(dest, src, l, coverage); x += l; + sx += l; length -= l; - sx = 0; + if (sx >= image_width) + sx = 0; } ++spans; } @@ -4464,7 +4466,9 @@ static void blend_tiled_rgb565(int count, const QSpan *spans, void *userData) memcpy(dest, src, l * sizeof(quint16)); length -= l; tx += l; - sx = 0; + sx += l; + if (sx >= image_width) + sx = 0; } // Now use the rasterBuffer as the source of the texture, @@ -4497,8 +4501,10 @@ static void blend_tiled_rgb565(int count, const QSpan *spans, void *userData) const quint16 *src = (const quint16 *)data->texture.scanLine(sy) + sx; blend_sourceOver_rgb16_rgb16(dest, src, l, alpha, ialpha); x += l; + sx += l; length -= l; - sx = 0; + if (sx >= image_width) + sx = 0; } } } diff --git a/src/gui/text/qfontengine_ft.cpp b/src/gui/text/qfontengine_ft.cpp index 09b0475a84..de6da88245 100644 --- a/src/gui/text/qfontengine_ft.cpp +++ b/src/gui/text/qfontengine_ft.cpp @@ -320,8 +320,9 @@ void QFreetypeFace::release(const QFontEngine::FaceId &face_id) cleanup(); - if (freetypeData->faces.contains(face_id)) - freetypeData->faces.take(face_id); + auto it = freetypeData->faces.constFind(face_id); + if (it != freetypeData->faces.constEnd()) + freetypeData->faces.erase(it); if (freetypeData->faces.isEmpty()) { FT_Done_FreeType(freetypeData->library); @@ -888,10 +889,47 @@ static inline bool areMetricsTooLarge(const QFontEngineFT::GlyphInfo &info) || (uchar)(info.height) != info.height; } +static inline void transformBoundingBox(int *left, int *top, int *right, int *bottom, FT_Matrix *matrix) +{ + int l, r, t, b; + FT_Vector vector; + vector.x = *left; + vector.y = *top; + FT_Vector_Transform(&vector, matrix); + l = r = vector.x; + t = b = vector.y; + vector.x = *right; + vector.y = *top; + FT_Vector_Transform(&vector, matrix); + if (l > vector.x) l = vector.x; + if (r < vector.x) r = vector.x; + if (t < vector.y) t = vector.y; + if (b > vector.y) b = vector.y; + vector.x = *right; + vector.y = *bottom; + FT_Vector_Transform(&vector, matrix); + if (l > vector.x) l = vector.x; + if (r < vector.x) r = vector.x; + if (t < vector.y) t = vector.y; + if (b > vector.y) b = vector.y; + vector.x = *left; + vector.y = *bottom; + FT_Vector_Transform(&vector, matrix); + if (l > vector.x) l = vector.x; + if (r < vector.x) r = vector.x; + if (t < vector.y) t = vector.y; + if (b > vector.y) b = vector.y; + *left = l; + *right = r; + *top = t; + *bottom = b; +} + QFontEngineFT::Glyph *QFontEngineFT::loadGlyph(QGlyphSet *set, uint glyph, QFixed subPixelPosition, GlyphFormat format, - bool fetchMetricsOnly) const + bool fetchMetricsOnly, + bool disableOutlineDrawing) const { // Q_ASSERT(freetype->lock == 1); @@ -976,11 +1014,20 @@ QFontEngineFT::Glyph *QFontEngineFT::loadGlyph(QGlyphSet *set, uint glyph, info.xOff = TRUNC(ROUND(slot->advance.x)); info.yOff = 0; - if ((set && set->outline_drawing) || fetchMetricsOnly) { - int left = FLOOR(slot->metrics.horiBearingX); - int right = CEIL(slot->metrics.horiBearingX + slot->metrics.width); - int top = CEIL(slot->metrics.horiBearingY); - int bottom = FLOOR(slot->metrics.horiBearingY - slot->metrics.height); + if ((set && set->outline_drawing && !disableOutlineDrawing) || fetchMetricsOnly) { + int left = slot->metrics.horiBearingX; + int right = slot->metrics.horiBearingX + slot->metrics.width; + int top = slot->metrics.horiBearingY; + int bottom = slot->metrics.horiBearingY - slot->metrics.height; + + if (transform && slot->format != FT_GLYPH_FORMAT_BITMAP) + transformBoundingBox(&left, &top, &right, &bottom, &matrix); + + left = FLOOR(left); + right = CEIL(right); + bottom = FLOOR(bottom); + top = CEIL(top); + info.x = TRUNC(left); info.y = TRUNC(top); info.width = TRUNC(right - left); @@ -1043,40 +1090,8 @@ QFontEngineFT::Glyph *QFontEngineFT::loadGlyph(QGlyphSet *set, uint glyph, int right = slot->metrics.horiBearingX + slot->metrics.width; int top = slot->metrics.horiBearingY; int bottom = slot->metrics.horiBearingY - slot->metrics.height; - if(transform && slot->format != FT_GLYPH_FORMAT_BITMAP) { - int l, r, t, b; - FT_Vector vector; - vector.x = left; - vector.y = top; - FT_Vector_Transform(&vector, &matrix); - l = r = vector.x; - t = b = vector.y; - vector.x = right; - vector.y = top; - FT_Vector_Transform(&vector, &matrix); - if (l > vector.x) l = vector.x; - if (r < vector.x) r = vector.x; - if (t < vector.y) t = vector.y; - if (b > vector.y) b = vector.y; - vector.x = right; - vector.y = bottom; - FT_Vector_Transform(&vector, &matrix); - if (l > vector.x) l = vector.x; - if (r < vector.x) r = vector.x; - if (t < vector.y) t = vector.y; - if (b > vector.y) b = vector.y; - vector.x = left; - vector.y = bottom; - FT_Vector_Transform(&vector, &matrix); - if (l > vector.x) l = vector.x; - if (r < vector.x) r = vector.x; - if (t < vector.y) t = vector.y; - if (b > vector.y) b = vector.y; - left = l; - right = r; - top = t; - bottom = b; - } + if (transform && slot->format != FT_GLYPH_FORMAT_BITMAP) + transformBoundingBox(&left, &top, &right, &bottom, &matrix); left = FLOOR(left); right = CEIL(right); bottom = FLOOR(bottom); @@ -1917,10 +1932,11 @@ QFontEngineFT::Glyph *QFontEngineFT::loadGlyphFor(glyph_t g, QFixed subPixelPosition, GlyphFormat format, const QTransform &t, - bool fetchBoundingBox) + bool fetchBoundingBox, + bool disableOutlineDrawing) { QGlyphSet *glyphSet = loadGlyphSet(t); - if (glyphSet != 0 && glyphSet->outline_drawing && !fetchBoundingBox) + if (glyphSet != 0 && glyphSet->outline_drawing && !disableOutlineDrawing && !fetchBoundingBox) return 0; Glyph *glyph = glyphSet != 0 ? glyphSet->getGlyph(g, subPixelPosition) : 0; @@ -1934,7 +1950,7 @@ QFontEngineFT::Glyph *QFontEngineFT::loadGlyphFor(glyph_t g, FT_Matrix ftMatrix = glyphSet != 0 ? glyphSet->transformationMatrix : QTransformToFTMatrix(t); FT_Matrix_Multiply(&ftMatrix, &m); freetype->matrix = m; - glyph = loadGlyph(glyphSet, g, subPixelPosition, format, false); + glyph = loadGlyph(glyphSet, g, subPixelPosition, format, false, disableOutlineDrawing); unlockFace(); } @@ -1950,7 +1966,7 @@ QImage QFontEngineFT::alphaMapForGlyph(glyph_t g, QFixed subPixelPosition, const { const GlyphFormat neededFormat = antialias ? Format_A8 : Format_Mono; - Glyph *glyph = loadGlyphFor(g, subPixelPosition, neededFormat, t); + Glyph *glyph = loadGlyphFor(g, subPixelPosition, neededFormat, t, false, true); QImage img = alphaMapFromGlyphData(glyph, neededFormat); img = img.copy(); @@ -1961,7 +1977,7 @@ QImage QFontEngineFT::alphaMapForGlyph(glyph_t g, QFixed subPixelPosition, const if (!img.isNull()) return img; - return QFontEngine::alphaMapForGlyph(g); + return QFontEngine::alphaMapForGlyph(g, subPixelPosition, t); } QImage QFontEngineFT::alphaRGBMapForGlyph(glyph_t g, QFixed subPixelPosition, const QTransform &t) @@ -1971,7 +1987,7 @@ QImage QFontEngineFT::alphaRGBMapForGlyph(glyph_t g, QFixed subPixelPosition, co const GlyphFormat neededFormat = Format_A32; - Glyph *glyph = loadGlyphFor(g, subPixelPosition, neededFormat, t); + Glyph *glyph = loadGlyphFor(g, subPixelPosition, neededFormat, t, false, true); QImage img = alphaMapFromGlyphData(glyph, neededFormat); img = img.copy(); diff --git a/src/gui/text/qfontengine_ft_p.h b/src/gui/text/qfontengine_ft_p.h index 5ca3721c71..32357d0076 100644 --- a/src/gui/text/qfontengine_ft_p.h +++ b/src/gui/text/qfontengine_ft_p.h @@ -272,10 +272,10 @@ private: inline bool isBitmapFont() const { return defaultFormat == Format_Mono; } inline bool isScalableBitmap() const { return freetype->isScalableBitmap(); } - inline Glyph *loadGlyph(uint glyph, QFixed subPixelPosition, GlyphFormat format = Format_None, bool fetchMetricsOnly = false) const - { return loadGlyph(cacheEnabled ? &defaultGlyphSet : 0, glyph, subPixelPosition, format, fetchMetricsOnly); } - Glyph *loadGlyph(QGlyphSet *set, uint glyph, QFixed subPixelPosition, GlyphFormat = Format_None, bool fetchMetricsOnly = false) const; - Glyph *loadGlyphFor(glyph_t g, QFixed subPixelPosition, GlyphFormat format, const QTransform &t, bool fetchBoundingBox = false); + inline Glyph *loadGlyph(uint glyph, QFixed subPixelPosition, GlyphFormat format = Format_None, bool fetchMetricsOnly = false, bool disableOutlineDrawing = false) const + { return loadGlyph(cacheEnabled ? &defaultGlyphSet : 0, glyph, subPixelPosition, format, fetchMetricsOnly, disableOutlineDrawing); } + Glyph *loadGlyph(QGlyphSet *set, uint glyph, QFixed subPixelPosition, GlyphFormat = Format_None, bool fetchMetricsOnly = false, bool disableOutlineDrawing = false) const; + Glyph *loadGlyphFor(glyph_t g, QFixed subPixelPosition, GlyphFormat format, const QTransform &t, bool fetchBoundingBox = false, bool disableOutlineDrawing = false); QGlyphSet *loadGlyphSet(const QTransform &matrix); diff --git a/src/gui/text/qrawfont.cpp b/src/gui/text/qrawfont.cpp index 886cf5ef39..b2d8bf01af 100644 --- a/src/gui/text/qrawfont.cpp +++ b/src/gui/text/qrawfont.cpp @@ -316,6 +316,19 @@ bool QRawFont::operator==(const QRawFont &other) const } /*! + Returns the hash value for \a font. If specified, \a seed is used + to initialize the hash. + + \relates QRawFont + \since 5.8 +*/ +uint qHash(const QRawFont &font, uint seed) Q_DECL_NOTHROW +{ + return qHash(QRawFontPrivate::get(font)->fontEngine, seed); +} + + +/*! \fn bool QRawFont::operator!=(const QRawFont &other) const Returns \c true if this QRawFont is not equal to \a other. Otherwise, returns \c false. diff --git a/src/gui/text/qrawfont.h b/src/gui/text/qrawfont.h index 0252e62370..470f2694e4 100644 --- a/src/gui/text/qrawfont.h +++ b/src/gui/text/qrawfont.h @@ -158,6 +158,8 @@ Q_DECLARE_SHARED(QRawFont) Q_DECLARE_OPERATORS_FOR_FLAGS(QRawFont::LayoutFlags) +Q_GUI_EXPORT uint qHash(const QRawFont &font, uint seed = 0) Q_DECL_NOTHROW; + inline QVector<QPointF> QRawFont::advancesForGlyphIndexes(const QVector<quint32> &glyphIndexes, QRawFont::LayoutFlags layoutFlags) const { QVector<QPointF> advances(glyphIndexes.size()); diff --git a/src/gui/text/qtextdocument.cpp b/src/gui/text/qtextdocument.cpp index 61bab2dbfd..5e9fac5f86 100644 --- a/src/gui/text/qtextdocument.cpp +++ b/src/gui/text/qtextdocument.cpp @@ -1785,6 +1785,10 @@ QTextBlock QTextDocument::lastBlock() const \property QTextDocument::pageSize \brief the page size that should be used for laying out the document + The units are determined by the underlying paint device. The size is + measured in logical pixels when painting to the screen, and in points + (1/72 inch) when painting to a printer. + By default, for a newly-created, empty document, this property contains an undefined size. diff --git a/src/gui/text/qtextformat.cpp b/src/gui/text/qtextformat.cpp index 8adeb3e659..39fec032dc 100644 --- a/src/gui/text/qtextformat.cpp +++ b/src/gui/text/qtextformat.cpp @@ -3409,8 +3409,7 @@ int QTextFormatCollection::indexForFormat(const QTextFormat &format) f.d = new QTextFormatPrivate; f.d->resolveFont(defaultFnt); - if (!hashes.contains(hash, idx)) - hashes.insert(hash, idx); + hashes.insert(hash, idx); } QT_CATCH(...) { formats.pop_back(); diff --git a/src/gui/text/qtextlayout.cpp b/src/gui/text/qtextlayout.cpp index adaac11517..023a1b7f52 100644 --- a/src/gui/text/qtextlayout.cpp +++ b/src/gui/text/qtextlayout.cpp @@ -1059,9 +1059,10 @@ QList<QGlyphRun> QTextLayout::glyphRuns(int from, int length) const QGlyphRun::GlyphRunFlags flags = glyphRun.flags(); QPair<QFontEngine *, int> key(fontEngine, int(flags)); // merge the glyph runs using the same font - if (glyphRunHash.contains(key)) { - QGlyphRun &oldGlyphRun = glyphRunHash[key]; - + QGlyphRun &oldGlyphRun = glyphRunHash[key]; + if (oldGlyphRun.isEmpty()) { + oldGlyphRun = glyphRun; + } else { QVector<quint32> indexes = oldGlyphRun.glyphIndexes(); QVector<QPointF> positions = oldGlyphRun.positions(); QRectF boundingRect = oldGlyphRun.boundingRect(); @@ -1073,8 +1074,6 @@ QList<QGlyphRun> QTextLayout::glyphRuns(int from, int length) const oldGlyphRun.setGlyphIndexes(indexes); oldGlyphRun.setPositions(positions); oldGlyphRun.setBoundingRect(boundingRect); - } else { - glyphRunHash[key] = glyphRun; } } } @@ -1908,11 +1907,15 @@ void QTextLine::layout_helper(int maxGlyphs) ++lbh.glyphCount; if (lbh.checkFullOtherwiseExtend(line)) goto found; - } else if (attributes[lbh.currentPosition].whiteSpace) { + } else if (attributes[lbh.currentPosition].whiteSpace + && eng->layoutData->string.at(lbh.currentPosition).decompositionTag() != QChar::NoBreak) { lbh.whiteSpaceOrObject = true; - while (lbh.currentPosition < end && attributes[lbh.currentPosition].whiteSpace) + while (lbh.currentPosition < end + && attributes[lbh.currentPosition].whiteSpace + && eng->layoutData->string.at(lbh.currentPosition).decompositionTag() != QChar::NoBreak) { addNextCluster(lbh.currentPosition, end, lbh.spaceData, lbh.glyphCount, current, lbh.logClusters, lbh.glyphs); + } if (!lbh.manualWrap && lbh.spaceData.textWidth > line.width) { lbh.spaceData.textWidth = line.width; // ignore spaces that fall out of the line. diff --git a/src/gui/text/text.pri b/src/gui/text/text.pri index c1c52f2d1a..a15793ec2f 100644 --- a/src/gui/text/text.pri +++ b/src/gui/text/text.pri @@ -32,11 +32,7 @@ HEADERS += \ text/qtextlist.h \ text/qsyntaxhighlighter.h \ text/qtextdocumentwriter.h \ - text/qcssparser_p.h \ text/qtexttable_p.h \ - text/qzipreader_p.h \ - text/qzipwriter_p.h \ - text/qtextodfwriter_p.h \ text/qstatictext_p.h \ text/qstatictext.h \ text/qrawfont.h \ @@ -70,9 +66,6 @@ SOURCES += \ text/qtextlist.cpp \ text/qtextdocumentwriter.cpp \ text/qsyntaxhighlighter.cpp \ - text/qcssparser.cpp \ - text/qzip.cpp \ - text/qtextodfwriter.cpp \ text/qstatictext.cpp \ text/qrawfont.cpp \ text/qglyphrun.cpp \ @@ -93,3 +86,20 @@ qtConfig(harfbuzz)|qtConfig(system-harfbuzz) { SOURCES += text/qharfbuzzng.cpp HEADERS += text/qharfbuzzng_p.h } + +qtConfig(textodfwriter) { + HEADERS += \ + text/qtextodfwriter_p.h \ + text/qzipreader_p.h \ + text/qzipwriter_p.h + SOURCES += \ + text/qtextodfwriter.cpp \ + text/qzip.cpp +} + +qtConfig(cssparser) { + HEADERS += \ + text/qcssparser_p.h + SOURCES += \ + text/qcssparser.cpp +} |