summaryrefslogtreecommitdiffstats
path: root/src/gui
diff options
context:
space:
mode:
authorFrederik Gladhorn <frederik.gladhorn@digia.com>2013-08-27 22:51:09 +0200
committerFrederik Gladhorn <frederik.gladhorn@digia.com>2013-08-27 22:51:09 +0200
commit190fa97c83472863fd886e86f626ab8196ed51b3 (patch)
tree49edb9f6a41d6c999c9bb43ae28911a8e7212757 /src/gui
parent3aa163491c9c8f28c88ac87cafc6418f2c0e46c5 (diff)
parent5971e0918757737425151c39a5f81a238663a17a (diff)
Merge remote-tracking branch 'origin/stable' into dev
Conflicts: examples/widgets/doc/src/addressbook-fr.qdoc Change-Id: Id1196e8e0c6445f1616c3f29234c974d809f8e48
Diffstat (limited to 'src/gui')
-rw-r--r--src/gui/kernel/qguiapplication.cpp2
-rw-r--r--src/gui/kernel/qwindow.cpp5
-rw-r--r--src/gui/opengl/qopenglfunctions_es2.h2
-rw-r--r--src/gui/painting/qbackingstore.cpp5
-rw-r--r--src/gui/text/qcssparser.cpp4
-rw-r--r--src/gui/text/qdistancefield.cpp270
-rw-r--r--src/gui/text/qdistancefield_p.h65
-rw-r--r--src/gui/text/qfontdatabase.cpp24
8 files changed, 320 insertions, 57 deletions
diff --git a/src/gui/kernel/qguiapplication.cpp b/src/gui/kernel/qguiapplication.cpp
index 6be3b066d8..eed1c41bfa 100644
--- a/src/gui/kernel/qguiapplication.cpp
+++ b/src/gui/kernel/qguiapplication.cpp
@@ -1664,7 +1664,7 @@ void QGuiApplicationPrivate::processKeyEvent(QWindowSystemInterfacePrivate::KeyE
) {
return;
}
- if (window->d_func()->blockedByModalWindow) {
+ if (window && window->d_func()->blockedByModalWindow) {
// a modal window is blocking this window, don't allow key events through
return;
}
diff --git a/src/gui/kernel/qwindow.cpp b/src/gui/kernel/qwindow.cpp
index 9ef19715ed..490cf0c110 100644
--- a/src/gui/kernel/qwindow.cpp
+++ b/src/gui/kernel/qwindow.cpp
@@ -348,8 +348,9 @@ void QWindowPrivate::updateVisibility()
void QWindowPrivate::setScreen(QScreen *newScreen, bool recreate)
{
Q_Q(QWindow);
- if (newScreen != q->screen()) {
- const bool shouldRecreate = recreate && platformWindow != 0;
+ if (newScreen != screen) {
+ const bool shouldRecreate = recreate && platformWindow != 0
+ && !(screen && screen->virtualSiblings().contains(newScreen));
if (shouldRecreate)
q->destroy();
if (screen)
diff --git a/src/gui/opengl/qopenglfunctions_es2.h b/src/gui/opengl/qopenglfunctions_es2.h
index 9c14567723..21ed6bec93 100644
--- a/src/gui/opengl/qopenglfunctions_es2.h
+++ b/src/gui/opengl/qopenglfunctions_es2.h
@@ -44,7 +44,7 @@
#include <QtCore/qglobal.h>
-#if defined(QT_OPENGL_ES_2)
+#if defined(QT_OPENGL_ES_2) || defined(Q_QDOC)
#include <QtGui/QOpenGLVersionFunctions>
#include <QtGui/qopenglcontext.h>
diff --git a/src/gui/painting/qbackingstore.cpp b/src/gui/painting/qbackingstore.cpp
index edb5f66c5b..c1f7c6c738 100644
--- a/src/gui/painting/qbackingstore.cpp
+++ b/src/gui/painting/qbackingstore.cpp
@@ -97,6 +97,11 @@ void QBackingStore::flush(const QRegion &region, QWindow *win, const QPoint &off
{
if (!win)
win = window();
+ if (!win->handle()) {
+ qWarning() << "QBackingStore::flush() called for "
+ << win << " which does not have a handle.";
+ return;
+ }
#ifdef QBACKINGSTORE_DEBUG
if (win && win->isTopLevel() && !qt_window_private(win)->receivedExpose) {
diff --git a/src/gui/text/qcssparser.cpp b/src/gui/text/qcssparser.cpp
index 1264330873..b486ec05fa 100644
--- a/src/gui/text/qcssparser.cpp
+++ b/src/gui/text/qcssparser.cpp
@@ -583,7 +583,11 @@ bool ValueExtractor::extractBorder(int *borders, QBrush *colors, BorderStyle *st
case BorderRightStyle: styles[RightEdge] = decl.styleValue(); break;
case BorderStyles: decl.styleValues(styles); break;
+#ifndef QT_OS_ANDROID_GCC_48_WORKAROUND
case BorderTopLeftRadius: radii[0] = sizeValue(decl); break;
+#else
+ case BorderTopLeftRadius: new(radii)QSize(sizeValue(decl)); break;
+#endif
case BorderTopRightRadius: radii[1] = sizeValue(decl); break;
case BorderBottomLeftRadius: radii[2] = sizeValue(decl); break;
case BorderBottomRightRadius: radii[3] = sizeValue(decl); break;
diff --git a/src/gui/text/qdistancefield.cpp b/src/gui/text/qdistancefield.cpp
index f4274a2c19..e584b66a25 100644
--- a/src/gui/text/qdistancefield.cpp
+++ b/src/gui/text/qdistancefield.cpp
@@ -487,15 +487,19 @@ static void drawPolygons(qint32 *bits, int width, int height, const QPoint *vert
}
}
-static QImage makeDistanceField(int imgWidth, int imgHeight, const QPainterPath &path, int dfScale, int offs)
+static void makeDistanceField(QDistanceFieldData *data, const QPainterPath &path, int dfScale, int offs)
{
- QImage image(imgWidth, imgHeight, QImage::Format_Indexed8);
+ if (!data || !data->data)
+ return;
if (path.isEmpty()) {
- image.fill(0);
- return image;
+ memset(data->data, 0, data->nbytes);
+ return;
}
+ int imgWidth = data->width;
+ int imgHeight = data->height;
+
QTransform transform;
transform.translate(offs, offs);
transform.scale(qreal(1) / dfScale, qreal(1) / dfScale);
@@ -521,8 +525,8 @@ static QImage makeDistanceField(int imgWidth, int imgHeight, const QPainterPath
QVarLengthArray<bool> isConvex;
QVarLengthArray<bool> needsClipping;
- drawPolygons(bits.data(), imgWidth, imgHeight, pathVertices.data(), indices, pathIndices.size(),
- interiorColor);
+ drawPolygons(bits.data(), imgWidth, imgHeight, pathVertices.data(),
+ indices, pathIndices.size(), interiorColor);
int index = 0;
@@ -681,15 +685,11 @@ static QImage makeDistanceField(int imgWidth, int imgHeight, const QPainterPath
}
const qint32 *inLine = bits.data();
- uchar *outLine = image.bits();
- int padding = image.bytesPerLine() - image.width();
+ uchar *outLine = data->data;
for (int y = 0; y < imgHeight; ++y) {
for (int x = 0; x < imgWidth; ++x, ++inLine, ++outLine)
*outLine = uchar((0x7f80 - *inLine) >> 8);
- outLine += padding;
}
-
- return image;
}
static bool imageHasNarrowOutlines(const QImage &im)
@@ -769,31 +769,96 @@ bool qt_fontHasNarrowOutlines(const QRawFont &f)
QRawFont::PixelAntialiasing));
}
-static QImage renderDistanceFieldPath(const QPainterPath &path, bool doubleResolution)
+
+QDistanceFieldData::QDistanceFieldData(const QDistanceFieldData &other)
+ : QSharedData(other)
+ , glyph(other.glyph)
+ , width(other.width)
+ , height(other.height)
+ , nbytes(other.nbytes)
+{
+ if (nbytes && other.data)
+ data = (uchar *)memcpy(malloc(nbytes), other.data, nbytes);
+ else
+ data = 0;
+}
+
+QDistanceFieldData::~QDistanceFieldData()
+{
+ free(data);
+}
+
+QDistanceFieldData *QDistanceFieldData::create(const QSize &size)
+{
+ QDistanceFieldData *data = new QDistanceFieldData;
+
+ if (size.isValid()) {
+ data->width = size.width();
+ data->height = size.height();
+ // pixel data stored as a 1-byte alpha value
+ data->nbytes = data->width * data->height; // tightly packed
+ data->data = (uchar *)malloc(data->nbytes);
+ }
+
+ return data;
+}
+
+QDistanceFieldData *QDistanceFieldData::create(const QPainterPath &path, bool doubleResolution)
{
int dfMargin = QT_DISTANCEFIELD_RADIUS(doubleResolution) / QT_DISTANCEFIELD_SCALE(doubleResolution);
int glyphWidth = qCeil(path.boundingRect().width() / QT_DISTANCEFIELD_SCALE(doubleResolution)) + dfMargin * 2;
- QImage im = makeDistanceField(glyphWidth,
- QT_DISTANCEFIELD_TILESIZE(doubleResolution),
- path,
- QT_DISTANCEFIELD_SCALE(doubleResolution),
- QT_DISTANCEFIELD_RADIUS(doubleResolution) / QT_DISTANCEFIELD_SCALE(doubleResolution));
- return im;
+ QDistanceFieldData *data = create(QSize(glyphWidth, QT_DISTANCEFIELD_TILESIZE(doubleResolution)));
+
+ makeDistanceField(data,
+ path,
+ QT_DISTANCEFIELD_SCALE(doubleResolution),
+ QT_DISTANCEFIELD_RADIUS(doubleResolution) / QT_DISTANCEFIELD_SCALE(doubleResolution));
+ return data;
}
-QImage qt_renderDistanceFieldGlyph(QFontEngine *fe, glyph_t glyph, bool doubleResolution)
+
+QDistanceField::QDistanceField()
+ : d(new QDistanceFieldData)
{
- QFixedPoint position;
- QPainterPath path;
- fe->addGlyphsToPath(&glyph, &position, 1, &path, 0);
- path.translate(-path.boundingRect().topLeft());
- path.setFillRule(Qt::WindingFill);
+}
- return renderDistanceFieldPath(path, doubleResolution);
+QDistanceField::QDistanceField(int width, int height)
+ : d(QDistanceFieldData::create(QSize(width, height)))
+{
}
-QImage qt_renderDistanceFieldGlyph(const QRawFont &font, glyph_t glyph, bool doubleResolution)
+QDistanceField::QDistanceField(const QDistanceField &other)
+{
+ d = other.d;
+}
+
+QDistanceField::QDistanceField(const QRawFont &font, glyph_t glyph, bool doubleResolution)
+{
+ setGlyph(font, glyph, doubleResolution);
+}
+
+QDistanceField::QDistanceField(QFontEngine *fontEngine, glyph_t glyph, bool doubleResolution)
+{
+ setGlyph(fontEngine, glyph, doubleResolution);
+}
+
+QDistanceField::QDistanceField(QDistanceFieldData *data)
+ : d(data)
+{
+}
+
+bool QDistanceField::isNull() const
+{
+ return !d->data;
+}
+
+glyph_t QDistanceField::glyph() const
+{
+ return d->glyph;
+}
+
+void QDistanceField::setGlyph(const QRawFont &font, glyph_t glyph, bool doubleResolution)
{
QRawFont renderFont = font;
renderFont.setPixelSize(QT_DISTANCEFIELD_BASEFONTSIZE(doubleResolution) * QT_DISTANCEFIELD_SCALE(doubleResolution));
@@ -802,7 +867,158 @@ QImage qt_renderDistanceFieldGlyph(const QRawFont &font, glyph_t glyph, bool dou
path.translate(-path.boundingRect().topLeft());
path.setFillRule(Qt::WindingFill);
- return renderDistanceFieldPath(path, doubleResolution);
+ d = QDistanceFieldData::create(path, doubleResolution);
+ d->glyph = glyph;
+}
+
+void QDistanceField::setGlyph(QFontEngine *fontEngine, glyph_t glyph, bool doubleResolution)
+{
+ QFixedPoint position;
+ QPainterPath path;
+ fontEngine->addGlyphsToPath(&glyph, &position, 1, &path, 0);
+ path.translate(-path.boundingRect().topLeft());
+ path.setFillRule(Qt::WindingFill);
+
+ d = QDistanceFieldData::create(path, doubleResolution);
+ d->glyph = glyph;
+}
+
+int QDistanceField::width() const
+{
+ return d->width;
+}
+
+int QDistanceField::height() const
+{
+ return d->height;
+}
+
+QDistanceField QDistanceField::copy(const QRect &r) const
+{
+ if (isNull())
+ return QDistanceField();
+
+ if (r.isNull())
+ return QDistanceField(new QDistanceFieldData(*d));
+
+ int x = r.x();
+ int y = r.y();
+ int w = r.width();
+ int h = r.height();
+
+ int dx = 0;
+ int dy = 0;
+ if (w <= 0 || h <= 0)
+ return QDistanceField();
+
+ QDistanceField df(w, h);
+ if (df.isNull())
+ return df;
+
+ if (x < 0 || y < 0 || x + w > d->width || y + h > d->height) {
+ memset(df.d->data, 0, df.d->nbytes);
+ if (x < 0) {
+ dx = -x;
+ x = 0;
+ }
+ if (y < 0) {
+ dy = -y;
+ y = 0;
+ }
+ }
+
+ int pixels_to_copy = qMax(w - dx, 0);
+ if (x > d->width)
+ pixels_to_copy = 0;
+ else if (pixels_to_copy > d->width - x)
+ pixels_to_copy = d->width - x;
+ int lines_to_copy = qMax(h - dy, 0);
+ if (y > d->height)
+ lines_to_copy = 0;
+ else if (lines_to_copy > d->height - y)
+ lines_to_copy = d->height - y;
+
+ const uchar *src = d->data + x + y * d->width;
+ uchar *dest = df.d->data + dx + dy * df.d->width;
+ for (int i = 0; i < lines_to_copy; ++i) {
+ memcpy(dest, src, pixels_to_copy);
+ src += d->width;
+ dest += df.d->width;
+ }
+
+ df.d->glyph = d->glyph;
+
+ return df;
+}
+
+uchar *QDistanceField::bits()
+{
+ return d->data;
+}
+
+const uchar *QDistanceField::bits() const
+{
+ return d->data;
+}
+
+const uchar *QDistanceField::constBits() const
+{
+ return d->data;
+}
+
+uchar *QDistanceField::scanLine(int i)
+{
+ if (isNull())
+ return 0;
+
+ Q_ASSERT(i >= 0 && i < d->height);
+ return d->data + i * d->width;
+}
+
+const uchar *QDistanceField::scanLine(int i) const
+{
+ if (isNull())
+ return 0;
+
+ Q_ASSERT(i >= 0 && i < d->height);
+ return d->data + i * d->width;
+}
+
+const uchar *QDistanceField::constScanLine(int i) const
+{
+ if (isNull())
+ return 0;
+
+ Q_ASSERT(i >= 0 && i < d->height);
+ return d->data + i * d->width;
+}
+
+QImage QDistanceField::toImage(QImage::Format format) const
+{
+ if (isNull())
+ return QImage();
+
+ QImage image(d->width, d->height, format == QImage::Format_Indexed8 ?
+ format : QImage::Format_ARGB32_Premultiplied);
+ if (image.isNull())
+ return image;
+
+ if (format == QImage::Format_Indexed8) {
+ for (int y = 0; y < d->height; ++y)
+ memcpy(image.scanLine(y), scanLine(y), d->width);
+ } else {
+ for (int y = 0; y < d->height; ++y) {
+ for (int x = 0; x < d->width; ++x) {
+ uint alpha = *(d->data + x + y * d->width);
+ image.setPixel(x, y, alpha << 24);
+ }
+ }
+
+ if (image.format() != format)
+ image = image.convertToFormat(format);
+ }
+
+ return image;
}
QT_END_NAMESPACE
diff --git a/src/gui/text/qdistancefield_p.h b/src/gui/text/qdistancefield_p.h
index f181aadd9d..d4c4f8f46d 100644
--- a/src/gui/text/qdistancefield_p.h
+++ b/src/gui/text/qdistancefield_p.h
@@ -55,6 +55,7 @@
#include <qrawfont.h>
#include <private/qfontengine_p.h>
+#include <QtCore/qshareddata.h>
QT_BEGIN_NAMESPACE
@@ -78,9 +79,69 @@ QT_BEGIN_NAMESPACE
QT_DISTANCEFIELD_DEFAULT_RADIUS)
bool Q_GUI_EXPORT qt_fontHasNarrowOutlines(const QRawFont &f);
-QImage Q_GUI_EXPORT qt_renderDistanceFieldGlyph(const QRawFont &font, glyph_t glyph, bool doubleResolution);
bool Q_GUI_EXPORT qt_fontHasNarrowOutlines(QFontEngine *fontEngine);
-QImage Q_GUI_EXPORT qt_renderDistanceFieldGlyph(QFontEngine *fontEngine, glyph_t glyph, bool doubleResolution);
+
+class Q_GUI_EXPORT QDistanceFieldData : public QSharedData
+{
+public:
+ QDistanceFieldData() : glyph(0), width(0), height(0), nbytes(0), data(0) {}
+ QDistanceFieldData(const QDistanceFieldData &other);
+ ~QDistanceFieldData();
+
+ static QDistanceFieldData *create(const QSize &size);
+ static QDistanceFieldData *create(const QPainterPath &path, bool doubleResolution);
+
+ glyph_t glyph;
+ int width;
+ int height;
+ int nbytes;
+ uchar *data;
+};
+
+class Q_GUI_EXPORT QDistanceField
+{
+public:
+ QDistanceField();
+ QDistanceField(int width, int height);
+ QDistanceField(const QRawFont &font, glyph_t glyph, bool doubleResolution = false);
+ QDistanceField(QFontEngine *fontEngine, glyph_t glyph, bool doubleResolution = false);
+ QDistanceField(const QDistanceField &other);
+
+ bool isNull() const;
+
+ glyph_t glyph() const;
+ void setGlyph(const QRawFont &font, glyph_t glyph, bool doubleResolution = false);
+ void setGlyph(QFontEngine *fontEngine, glyph_t glyph, bool doubleResolution = false);
+
+ int width() const;
+ int height() const;
+
+ QDistanceField copy(const QRect &rect = QRect()) const;
+ inline QDistanceField copy(int x, int y, int w, int h) const
+ { return copy(QRect(x, y, w, h)); }
+
+ uchar *bits();
+ const uchar *bits() const;
+ const uchar *constBits() const;
+
+ uchar *scanLine(int);
+ const uchar *scanLine(int) const;
+ const uchar *constScanLine(int) const;
+
+ QImage toImage(QImage::Format format = QImage::Format_ARGB32_Premultiplied) const;
+
+private:
+ QDistanceField(QDistanceFieldData *data);
+ QSharedDataPointer<QDistanceFieldData> d;
+
+ friend class QDistanceFieldData;
+};
+
+
+inline QImage Q_GUI_EXPORT qt_renderDistanceFieldGlyph(const QRawFont &f, glyph_t g, bool d)
+{ return QDistanceField(f, g, d).toImage(QImage::Format_Indexed8); }
+inline QImage Q_GUI_EXPORT qt_renderDistanceFieldGlyph(QFontEngine *fe, glyph_t g, bool d)
+{ return QDistanceField(fe, g, d).toImage(QImage::Format_Indexed8); }
QT_END_NAMESPACE
diff --git a/src/gui/text/qfontdatabase.cpp b/src/gui/text/qfontdatabase.cpp
index 2e4f341e39..97ac604197 100644
--- a/src/gui/text/qfontdatabase.cpp
+++ b/src/gui/text/qfontdatabase.cpp
@@ -315,9 +315,6 @@ struct QtFontFamily
QtFontFamily(const QString &n)
:
fixedPitch(false),
-#if !defined(QWS) && defined(Q_OS_MAC)
- fixedPitchComputed(false),
-#endif
name(n), count(0), foundries(0)
, bogusWritingSystems(false)
, askedForFallback(false)
@@ -331,9 +328,6 @@ struct QtFontFamily
}
bool fixedPitch : 1;
-#if !defined(QWS) && defined(Q_OS_MAC)
- bool fixedPitchComputed : 1;
-#endif
QString name;
QStringList aliases;
@@ -349,18 +343,6 @@ struct QtFontFamily
QtFontFoundry *foundry(const QString &f, bool = false);
};
-#if !defined(QWS) && defined(Q_OS_MAC)
-inline static void qt_mac_get_fixed_pitch(QtFontFamily *f)
-{
- if(f && !f->fixedPitchComputed) {
- QFontMetrics fm(f->name);
- f->fixedPitch = fm.width(QLatin1Char('i')) == fm.width(QLatin1Char('m'));
- f->fixedPitchComputed = true;
- }
-}
-#endif
-
-
QtFontFoundry *QtFontFamily::foundry(const QString &f, bool create)
{
if (f.isNull() && count == 1)
@@ -824,9 +806,6 @@ unsigned int bestFoundry(int script, unsigned int score, int styleStrategy,
EncodingMismatch = 0x0002
};
if (pitch != '*') {
-#if !defined(QWS) && defined(Q_OS_MAC)
- qt_mac_get_fixed_pitch(const_cast<QtFontFamily*>(family));
-#endif
if ((pitch == 'm' && !family->fixedPitch)
|| (pitch == 'p' && family->fixedPitch))
this_score += PitchMismatch;
@@ -1275,9 +1254,6 @@ bool QFontDatabase::isFixedPitch(const QString &family,
QT_PREPEND_NAMESPACE(load)(familyName);
QtFontFamily *f = d->family(familyName);
-#if !defined(QWS) && defined(Q_OS_MAC)
- qt_mac_get_fixed_pitch(f);
-#endif
return (f && f->fixedPitch);
}