diff options
author | Sergio Ahumada <sergio.ahumada@digia.com> | 2013-09-02 15:07:53 +0200 |
---|---|---|
committer | The Qt Project <gerrit-noreply@qt-project.org> | 2013-09-02 16:26:21 +0200 |
commit | 0a3eb0fe443f8158d81d97cde8f0c9a9632fb9f0 (patch) | |
tree | 7bbdc72a7e30e23fc66a610ff7e3cd298711e5b1 /src/gui | |
parent | cee7380c0470dc591e2aafb3225641d4194ab05c (diff) | |
parent | 190fa97c83472863fd886e86f626ab8196ed51b3 (diff) |
Merge "Merge remote-tracking branch 'origin/stable' into dev" into refs/staging/dev
Diffstat (limited to 'src/gui')
-rw-r--r-- | src/gui/kernel/qguiapplication.cpp | 2 | ||||
-rw-r--r-- | src/gui/kernel/qwindow.cpp | 5 | ||||
-rw-r--r-- | src/gui/opengl/qopenglfunctions_es2.h | 2 | ||||
-rw-r--r-- | src/gui/painting/qbackingstore.cpp | 5 | ||||
-rw-r--r-- | src/gui/text/qcssparser.cpp | 4 | ||||
-rw-r--r-- | src/gui/text/qdistancefield.cpp | 270 | ||||
-rw-r--r-- | src/gui/text/qdistancefield_p.h | 65 | ||||
-rw-r--r-- | src/gui/text/qfontdatabase.cpp | 24 |
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 ®ion, 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); } |