summaryrefslogtreecommitdiffstats
path: root/src/gui
diff options
context:
space:
mode:
authorLiang Qi <liang.qi@qt.io>2016-11-18 08:01:52 +0000
committerThe Qt Project <gerrit-noreply@qt-project.org>2016-11-18 08:01:52 +0000
commit3a0764d625a18233006ca438226281bc3c6740c5 (patch)
treeb40076ee56d61cc4491a2326784e435e39ea6883 /src/gui
parentdafd0955c601fc00f9164f9b955ec9f28b627565 (diff)
parente5ac4afbf954a3e1616ce8543d46ddc668d0374f (diff)
Merge "Merge remote-tracking branch 'origin/5.8' into dev" into refs/staging/dev
Diffstat (limited to 'src/gui')
-rw-r--r--src/gui/configure.json10
-rw-r--r--src/gui/configure.pri2
-rw-r--r--src/gui/image/qicon.cpp2
-rw-r--r--src/gui/image/qiconloader.cpp6
-rw-r--r--src/gui/image/qpixmapcache.cpp19
-rw-r--r--src/gui/kernel/kernel.pri2
-rw-r--r--src/gui/kernel/qhighdpiscaling.cpp6
-rw-r--r--src/gui/kernel/qopenglcontext.cpp5
-rw-r--r--src/gui/kernel/qopenglcontext_p.h2
-rw-r--r--src/gui/kernel/qwindow.cpp3
-rw-r--r--src/gui/opengl/opengl.pri2
-rw-r--r--src/gui/opengl/qopengl.cpp6
-rw-r--r--src/gui/opengl/qopengl.h18
-rw-r--r--src/gui/opengl/qopenglframebufferobject.cpp6
-rw-r--r--src/gui/opengl/qopenglshaderprogram.cpp81
-rw-r--r--src/gui/painting/painting.pri12
-rw-r--r--src/gui/painting/qdrawhelper.cpp12
-rw-r--r--src/gui/text/qfontengine_ft.cpp112
-rw-r--r--src/gui/text/qfontengine_ft_p.h8
-rw-r--r--src/gui/text/qrawfont.cpp13
-rw-r--r--src/gui/text/qrawfont.h2
-rw-r--r--src/gui/text/qtextdocument.cpp4
-rw-r--r--src/gui/text/qtextformat.cpp3
-rw-r--r--src/gui/text/qtextlayout.cpp17
-rw-r--r--src/gui/text/text.pri24
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
+}