diff options
author | Michael Brasser <michael.brasser@nokia.com> | 2009-10-19 22:33:29 (GMT) |
---|---|---|
committer | Michael Brasser <michael.brasser@nokia.com> | 2009-10-19 22:33:29 (GMT) |
commit | ae1cb61204530099f438656226a4b24449658203 (patch) | |
tree | 485a961f295ab0db5b60cdd62f6072ac2368dfe6 /src/gui | |
parent | 55bddd50925da27f7a106041db44c15057aac6c1 (diff) | |
parent | 02c15e6a8cdb0f8a0bb6ee36880877fe90334d69 (diff) | |
download | Qt-ae1cb61204530099f438656226a4b24449658203.zip Qt-ae1cb61204530099f438656226a4b24449658203.tar.gz Qt-ae1cb61204530099f438656226a4b24449658203.tar.bz2 |
Merge branch '4.6' of git@scm.dev.nokia.troll.no:qt/qt into kinetic-declarativeui
Conflicts:
tools/qdoc3/cppcodemarker.cpp
Diffstat (limited to 'src/gui')
29 files changed, 330 insertions, 183 deletions
diff --git a/src/gui/effects/qgraphicseffect.cpp b/src/gui/effects/qgraphicseffect.cpp index ee01fdc..91641b0 100644 --- a/src/gui/effects/qgraphicseffect.cpp +++ b/src/gui/effects/qgraphicseffect.cpp @@ -105,6 +105,7 @@ #include <QtGui/qpainter.h> #include <QtCore/qrect.h> #include <QtCore/qdebug.h> +#include <private/qdrawhelper_p.h> QT_BEGIN_NAMESPACE @@ -893,15 +894,8 @@ void QGraphicsBlurEffect::draw(QPainter *painter, QGraphicsEffectSource *source) return; } - QPoint offset; - if (source->isPixmap()) { - // No point in drawing in device coordinates (pixmap will be scaled anyways). - const QPixmap pixmap = source->pixmap(Qt::LogicalCoordinates, &offset); - d->filter->draw(painter, offset, pixmap); - return; - } - // Draw pixmap in device coordinates to avoid pixmap scaling. + QPoint offset; const QPixmap pixmap = source->pixmap(Qt::DeviceCoordinates, &offset); QTransform restoreTransform = painter->worldTransform(); painter->setWorldTransform(QTransform()); @@ -1084,15 +1078,8 @@ void QGraphicsDropShadowEffect::draw(QPainter *painter, QGraphicsEffectSource *s return; } - QPoint offset; - if (source->isPixmap()) { - // No point in drawing in device coordinates (pixmap will be scaled anyways). - const QPixmap pixmap = source->pixmap(Qt::LogicalCoordinates, &offset); - d->filter->draw(painter, offset, pixmap); - return; - } - // Draw pixmap in device coordinates to avoid pixmap scaling. + QPoint offset; const QPixmap pixmap = source->pixmap(Qt::DeviceCoordinates, &offset); QTransform restoreTransform = painter->worldTransform(); painter->setWorldTransform(QTransform()); @@ -1475,6 +1462,8 @@ void QGraphicsBloomEffect::setStrength(qreal strength) The \a strength parameter holds the effect's new strength. */ +extern QPixmap qt_toRasterPixmap(const QPixmap &pixmap); + /*! \reimp */ @@ -1486,42 +1475,37 @@ void QGraphicsBloomEffect::draw(QPainter *painter, QGraphicsEffectSource *source return; } - const Qt::CoordinateSystem system = source->isPixmap() - ? Qt::LogicalCoordinates : Qt::DeviceCoordinates; QPoint offset; - QPixmap pixmap = source->pixmap(system, &offset); - QImage result = pixmap.toImage().convertToFormat(QImage::Format_ARGB32_Premultiplied); + QPixmap pixmap = qt_toRasterPixmap(source->pixmap(Qt::DeviceCoordinates, &offset)); // Blur. - QPainter blurPainter(&pixmap); + QImage overlay(pixmap.size(), QImage::Format_ARGB32_Premultiplied); + overlay.fill(0); + + QPainter blurPainter(&overlay); d->blurFilter.draw(&blurPainter, QPointF(), pixmap); blurPainter.end(); // Brighten. - QImage overlay = pixmap.toImage().convertToFormat(QImage::Format_ARGB32); const int numBits = overlay.width() * overlay.height(); QRgb *bits = reinterpret_cast<QRgb *>(overlay.bits()); for (int i = 0; i < numBits; ++i) { - const QRgb bit = bits[i]; - bits[i] = qRgba(d->colorTable[qRed(bit)], d->colorTable[qGreen(bit)], - d->colorTable[qBlue(bit)], qAlpha(bit)); + const QRgb pixel = INV_PREMUL(bits[i]); + bits[i] = PREMUL(qRgba(d->colorTable[qRed(pixel)], d->colorTable[qGreen(pixel)], + d->colorTable[qBlue(pixel)], qAlpha(pixel))); } // Composite. - QPainter compPainter(&result); + QPainter compPainter(&pixmap); compPainter.setCompositionMode(QPainter::CompositionMode_Overlay); compPainter.setOpacity(d->strength); compPainter.drawImage(0, 0, overlay); compPainter.end(); - if (system == Qt::DeviceCoordinates) { - QTransform restoreTransform = painter->worldTransform(); - painter->setWorldTransform(QTransform()); - painter->drawImage(offset, result); - painter->setWorldTransform(restoreTransform); - } else { - painter->drawImage(offset, result); - } + QTransform restoreTransform = painter->worldTransform(); + painter->setWorldTransform(QTransform()); + painter->drawPixmap(offset, pixmap); + painter->setWorldTransform(restoreTransform); } QT_END_NAMESPACE diff --git a/src/gui/image/qimage.cpp b/src/gui/image/qimage.cpp index 9048387..21ab40c 100644 --- a/src/gui/image/qimage.cpp +++ b/src/gui/image/qimage.cpp @@ -377,6 +377,9 @@ bool QImageData::checkForAlphaPixels() const \note If you would like to load QImage objects in a static build of Qt, refer to the \l{How To Create Qt Plugins#Static Plugins}{Plugin HowTo}. + \warning Painting on a QImage with the format + QImage::Format_Indexed8 is not supported. + \tableofcontents \section1 Reading and Writing Image Files diff --git a/src/gui/image/qpixmap.cpp b/src/gui/image/qpixmap.cpp index 558ae54..c03a364 100644 --- a/src/gui/image/qpixmap.cpp +++ b/src/gui/image/qpixmap.cpp @@ -361,13 +361,7 @@ QPixmap QPixmap::copy(const QRect &rect) const const QRect r = rect.isEmpty() ? QRect(0, 0, width(), height()) : rect; - QPixmapData *d; - QGraphicsSystem* gs = QApplicationPrivate::graphicsSystem(); - if (gs) - d = gs->createPixmapData(data->pixelType()); - else - d = QGraphicsSystem::createDefaultPixmapData(data->pixelType()); - + QPixmapData *d = data->createCompatiblePixmapData(); d->copy(data.data(), r); return QPixmap(d); } @@ -947,6 +941,9 @@ bool QPixmap::doImageIO(QImageWriter *writer, int quality) const /*! Fills the pixmap with the given \a color. + The effect of this function is undefined when the pixmap is + being painted on. + \sa {QPixmap#Pixmap Transformations}{Pixmap Transformations} */ @@ -955,6 +952,13 @@ void QPixmap::fill(const QColor &color) if (isNull()) return; + // Some people are probably already calling fill while a painter is active, so to not break + // their programs, only print a warning and return when the fill operation could cause a crash. + if (paintingActive() && (color.alpha() != 255) && !hasAlphaChannel()) { + qWarning("QPixmap::fill: Cannot fill while pixmap is being painted on"); + return; + } + detach(); data->fill(color); } @@ -1663,10 +1667,10 @@ QPixmap QPixmap::transformed(const QMatrix &matrix, Qt::TransformationMode mode) identifies the contents of the QPixmap object. The x11Info() function returns information about the configuration - of the X display used to display the widget. The - x11PictureHandle() function returns the X11 Picture handle of the - pixmap for XRender support. Note that the two latter functions are - only available on x11. + of the X display used by the screen to which the pixmap currently + belongs. The x11PictureHandle() function returns the X11 Picture + handle of the pixmap for XRender support. Note that the two latter + functions are only available on x11. \endtable @@ -2084,7 +2088,7 @@ QPixmapData* QPixmap::pixmapData() const /*! \fn const QX11Info &QPixmap::x11Info() const \bold{X11 only:} Returns information about the configuration of - the X display used to display the widget. + the X display used by the screen to which the pixmap currently belongs. \warning This function is only available on X11. diff --git a/src/gui/image/qpixmap_mac.cpp b/src/gui/image/qpixmap_mac.cpp index de532fd..afa6f83 100644 --- a/src/gui/image/qpixmap_mac.cpp +++ b/src/gui/image/qpixmap_mac.cpp @@ -166,6 +166,11 @@ QMacPixmapData::QMacPixmapData(PixelType type) { } +QPixmapData *QMacPixmapData::createCompatiblePixmapData() const +{ + return new QMacPixmapData(pixelType()); +} + #define BEST_BYTE_ALIGNMENT 16 #define COMPTUE_BEST_BYTES_PER_ROW(bpr) \ (((bpr) + (BEST_BYTE_ALIGNMENT - 1)) & ~(BEST_BYTE_ALIGNMENT - 1)) diff --git a/src/gui/image/qpixmap_mac_p.h b/src/gui/image/qpixmap_mac_p.h index 528dd1f..a3fb95f 100644 --- a/src/gui/image/qpixmap_mac_p.h +++ b/src/gui/image/qpixmap_mac_p.h @@ -65,6 +65,8 @@ public: QMacPixmapData(PixelType type); ~QMacPixmapData(); + QPixmapData *createCompatiblePixmapData() const; + void resize(int width, int height); void fromImage(const QImage &image, Qt::ImageConversionFlags flags); void copy(const QPixmapData *data, const QRect &rect); diff --git a/src/gui/image/qpixmap_raster.cpp b/src/gui/image/qpixmap_raster.cpp index ad68b07..fc76dc3 100644 --- a/src/gui/image/qpixmap_raster.cpp +++ b/src/gui/image/qpixmap_raster.cpp @@ -55,6 +55,29 @@ QT_BEGIN_NAMESPACE const uchar qt_pixmap_bit_mask[] = { 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80 }; +QPixmap qt_toRasterPixmap(const QImage &image) +{ + QPixmapData *data = + new QRasterPixmapData(image.depth() == 1 + ? QPixmapData::BitmapType + : QPixmapData::PixmapType); + + data->fromImage(image, Qt::AutoColor); + + return QPixmap(data); +} + +QPixmap qt_toRasterPixmap(const QPixmap &pixmap) +{ + if (pixmap.isNull()) + return QPixmap(); + + if (QPixmap(pixmap).data_ptr()->classId() == QPixmapData::RasterClass) + return pixmap; + + return qt_toRasterPixmap(pixmap.toImage()); +} + QRasterPixmapData::QRasterPixmapData(PixelType type) : QPixmapData(type, RasterClass) { @@ -64,6 +87,11 @@ QRasterPixmapData::~QRasterPixmapData() { } +QPixmapData *QRasterPixmapData::createCompatiblePixmapData() const +{ + return new QRasterPixmapData(pixelType()); +} + void QRasterPixmapData::resize(int width, int height) { QImage::Format format; diff --git a/src/gui/image/qpixmap_raster_p.h b/src/gui/image/qpixmap_raster_p.h index da0405e..1553940 100644 --- a/src/gui/image/qpixmap_raster_p.h +++ b/src/gui/image/qpixmap_raster_p.h @@ -68,6 +68,8 @@ public: QRasterPixmapData(PixelType type); ~QRasterPixmapData(); + QPixmapData *createCompatiblePixmapData() const; + void resize(int width, int height); void fromFile(const QString &filename, Qt::ImageConversionFlags flags); void fromImage(const QImage &image, Qt::ImageConversionFlags flags); diff --git a/src/gui/image/qpixmap_x11.cpp b/src/gui/image/qpixmap_x11.cpp index 74543a0..ea9eff9 100644 --- a/src/gui/image/qpixmap_x11.cpp +++ b/src/gui/image/qpixmap_x11.cpp @@ -319,6 +319,11 @@ QX11PixmapData::QX11PixmapData(PixelType type) { } +QPixmapData *QX11PixmapData::createCompatiblePixmapData() const +{ + return new QX11PixmapData(pixelType()); +} + void QX11PixmapData::resize(int width, int height) { setSerialNumber(++qt_pixmap_serial); diff --git a/src/gui/image/qpixmap_x11_p.h b/src/gui/image/qpixmap_x11_p.h index e34e690..2d6672d 100644 --- a/src/gui/image/qpixmap_x11_p.h +++ b/src/gui/image/qpixmap_x11_p.h @@ -71,6 +71,8 @@ public: // Qt::ImageConversionFlags flags); ~QX11PixmapData(); + QPixmapData *createCompatiblePixmapData() const; + void resize(int width, int height); void fromImage(const QImage &image, Qt::ImageConversionFlags flags); void copy(const QPixmapData *data, const QRect &rect); diff --git a/src/gui/image/qpixmapcache.cpp b/src/gui/image/qpixmapcache.cpp index f12d397..b0b7d72 100644 --- a/src/gui/image/qpixmapcache.cpp +++ b/src/gui/image/qpixmapcache.cpp @@ -221,6 +221,7 @@ QPMCache::QPMCache() } QPMCache::~QPMCache() { + clear(); free(keyArray); } diff --git a/src/gui/image/qpixmapdata.cpp b/src/gui/image/qpixmapdata.cpp index 93fc2eb..1ad1f02 100644 --- a/src/gui/image/qpixmapdata.cpp +++ b/src/gui/image/qpixmapdata.cpp @@ -43,6 +43,8 @@ #include <QtCore/qbuffer.h> #include <QtGui/qbitmap.h> #include <QtGui/qimagereader.h> +#include <private/qgraphicssystem_p.h> +#include <private/qapplication_p.h> QT_BEGIN_NAMESPACE @@ -67,6 +69,17 @@ QPixmapData::~QPixmapData() { } +QPixmapData *QPixmapData::createCompatiblePixmapData() const +{ + QPixmapData *d; + QGraphicsSystem *gs = QApplicationPrivate::graphicsSystem(); + if (gs) + d = gs->createPixmapData(pixelType()); + else + d = QGraphicsSystem::createDefaultPixmapData(pixelType()); + return d; +} + static QImage makeBitmapCompliantIfNeeded(QPixmapData *d, const QImage &image, Qt::ImageConversionFlags flags) { if (d->pixelType() == QPixmapData::BitmapType) { diff --git a/src/gui/image/qpixmapdata_p.h b/src/gui/image/qpixmapdata_p.h index c26fba3..2f4f201 100644 --- a/src/gui/image/qpixmapdata_p.h +++ b/src/gui/image/qpixmapdata_p.h @@ -75,9 +75,11 @@ public: enum ClassId { RasterClass, X11Class, MacClass, DirectFBClass, OpenGLClass, OpenVGClass, CustomClass = 1024 }; - QPixmapData(PixelType pixelpType, int classId); + QPixmapData(PixelType pixelType, int classId); virtual ~QPixmapData(); + virtual QPixmapData *createCompatiblePixmapData() const; + virtual void resize(int width, int height) = 0; virtual void fromImage(const QImage &image, Qt::ImageConversionFlags flags) = 0; diff --git a/src/gui/image/qpixmapfilter.cpp b/src/gui/image/qpixmapfilter.cpp index df445db..9fcf776 100644 --- a/src/gui/image/qpixmapfilter.cpp +++ b/src/gui/image/qpixmapfilter.cpp @@ -591,7 +591,7 @@ QRectF QPixmapBlurFilter::boundingRectFor(const QRectF &rect) const // Blur the image according to the blur radius // Based on exponential blur algorithm by Jani Huhtanen // (maximum radius is set to 16) -static QImage blurred(const QImage& image, const QRect& rect, int radius) +static QImage blurred(const QImage& image, const QRect& rect, int radius, bool alphaOnly = false) { int tab[] = { 14, 10, 8, 6, 5, 5, 4, 3, 3, 3, 3, 2, 2, 2, 2, 2, 2 }; int alpha = (radius < 1) ? 16 : (radius > 17) ? 1 : tab[radius-1]; @@ -606,47 +606,53 @@ static QImage blurred(const QImage& image, const QRect& rect, int radius) int rgba[4]; unsigned char* p; + int i1 = 0; + int i2 = 3; + + if (alphaOnly) + i1 = i2 = (QSysInfo::ByteOrder == QSysInfo::BigEndian ? 0 : 3); + for (int col = c1; col <= c2; col++) { p = result.scanLine(r1) + col * 4; - for (int i = 0; i < 4; i++) + for (int i = i1; i <= i2; i++) rgba[i] = p[i] << 4; p += bpl; for (int j = r1; j < r2; j++, p += bpl) - for (int i = 0; i < 4; i++) + for (int i = i1; i <= i2; i++) p[i] = (rgba[i] += ((p[i] << 4) - rgba[i]) * alpha / 16) >> 4; } for (int row = r1; row <= r2; row++) { p = result.scanLine(row) + c1 * 4; - for (int i = 0; i < 4; i++) + for (int i = i1; i <= i2; i++) rgba[i] = p[i] << 4; p += 4; for (int j = c1; j < c2; j++, p += 4) - for (int i = 0; i < 4; i++) + for (int i = i1; i <= i2; i++) p[i] = (rgba[i] += ((p[i] << 4) - rgba[i]) * alpha / 16) >> 4; } for (int col = c1; col <= c2; col++) { p = result.scanLine(r2) + col * 4; - for (int i = 0; i < 4; i++) + for (int i = i1; i <= i2; i++) rgba[i] = p[i] << 4; p -= bpl; for (int j = r1; j < r2; j++, p -= bpl) - for (int i = 0; i < 4; i++) + for (int i = i1; i <= i2; i++) p[i] = (rgba[i] += ((p[i] << 4) - rgba[i]) * alpha / 16) >> 4; } for (int row = r1; row <= r2; row++) { p = result.scanLine(row) + c2 * 4; - for (int i = 0; i < 4; i++) + for (int i = i1; i <= i2; i++) rgba[i] = p[i] << 4; p -= 4; for (int j = c1; j < c2; j++, p -= 4) - for (int i = 0; i < 4; i++) + for (int i = i1; i <= i2; i++) p[i] = (rgba[i] += ((p[i] << 4) - rgba[i]) * alpha / 16) >> 4; } @@ -892,11 +898,11 @@ class QPixmapDropShadowFilterPrivate : public QPixmapFilterPrivate { public: QPixmapDropShadowFilterPrivate() - : offset(8, 8), color(63, 63, 63, 180), blurFilter(new QPixmapBlurFilter) {} + : offset(8, 8), color(63, 63, 63, 180), radius(1) {} QPointF offset; QColor color; - QPixmapBlurFilter *blurFilter; + int radius; }; /*! @@ -940,8 +946,6 @@ public: QPixmapDropShadowFilter::QPixmapDropShadowFilter(QObject *parent) : QPixmapFilter(*new QPixmapDropShadowFilterPrivate, DropShadowFilter, parent) { - Q_D(QPixmapDropShadowFilter); - d->blurFilter->setRadius(1); } /*! @@ -951,8 +955,6 @@ QPixmapDropShadowFilter::QPixmapDropShadowFilter(QObject *parent) */ QPixmapDropShadowFilter::~QPixmapDropShadowFilter() { - Q_D(QPixmapDropShadowFilter); - delete d->blurFilter; } /*! @@ -967,7 +969,7 @@ QPixmapDropShadowFilter::~QPixmapDropShadowFilter() int QPixmapDropShadowFilter::blurRadius() const { Q_D(const QPixmapDropShadowFilter); - return d->blurFilter->radius(); + return d->radius; } /*! @@ -982,7 +984,7 @@ int QPixmapDropShadowFilter::blurRadius() const void QPixmapDropShadowFilter::setBlurRadius(int radius) { Q_D(QPixmapDropShadowFilter); - d->blurFilter->setRadius(radius); + d->radius = radius; } /*! @@ -1056,7 +1058,7 @@ QRectF QPixmapDropShadowFilter::boundingRectFor(const QRectF &rect) const { Q_D(const QPixmapDropShadowFilter); - const qreal delta = qreal(d->blurFilter->radius() * 2); + const qreal delta = qreal(d->radius * 2); qreal x1 = qMin(rect.left(), rect.left() + d->offset.x() - delta); qreal y1 = qMin(rect.top(), rect.top() + d->offset.y() - delta); qreal x2 = qMax(rect.right(), rect.right() + d->offset.x() + delta); @@ -1079,24 +1081,25 @@ void QPixmapDropShadowFilter::draw(QPainter *p, QPixmapDropShadowFilter *dropShadowFilter = static_cast<QPixmapDropShadowFilter*>(filter); if (dropShadowFilter) { dropShadowFilter->setColor(d->color); - dropShadowFilter->setBlurRadius(d->blurFilter->radius()); + dropShadowFilter->setBlurRadius(d->radius); dropShadowFilter->setOffset(d->offset); dropShadowFilter->draw(p, pos, px, src); return; } - QImage tmp = src.isNull() ? px.toImage() : px.copy(src.toRect()).toImage(); - QPainter tmpPainter(&tmp); + QImage tmp = src.isNull() ? px.toImage() : px.copy(src.toAlignedRect()).toImage(); + + // blur the alpha channel + tmp = blurred(tmp, tmp.rect(), d->radius, true); // blacken the image... + QPainter tmpPainter(&tmp); tmpPainter.setCompositionMode(QPainter::CompositionMode_SourceIn); tmpPainter.fillRect(0, 0, tmp.width(), tmp.height(), d->color); tmpPainter.end(); - const QPixmap pixTmp = QPixmap::fromImage(tmp); - // draw the blurred drop shadow... - d->blurFilter->draw(p, pos + d->offset, pixTmp); + p->drawImage(pos + d->offset, tmp); // Draw the actual pixmap... p->drawPixmap(pos, px, src); diff --git a/src/gui/inputmethod/qmacinputcontext_mac.cpp b/src/gui/inputmethod/qmacinputcontext_mac.cpp index 116d233..994edb9 100644 --- a/src/gui/inputmethod/qmacinputcontext_mac.cpp +++ b/src/gui/inputmethod/qmacinputcontext_mac.cpp @@ -217,7 +217,11 @@ QMacInputContext::globalEventProcessor(EventHandlerCallRef, EventRef event, void case kEventClassTextInput: { handled_event = false; QWidget *widget = QApplicationPrivate::focus_widget; - if(!widget || (context && widget->inputContext() != context)) { + bool canCompose = widget && (!context || widget->inputContext() == context) + && !(widget->inputMethodHints() & Qt::ImhDigitsOnly + || widget->inputMethodHints() & Qt::ImhFormattedNumbersOnly + || widget->inputMethodHints() & Qt::ImhHiddenText); + if(!canCompose) { handled_event = false; } else if(ekind == kEventTextInputOffsetToPos) { if(!widget->testAttribute(Qt::WA_InputMethodEnabled)) { diff --git a/src/gui/kernel/qaction.cpp b/src/gui/kernel/qaction.cpp index 6a6e549..5f5650f 100644 --- a/src/gui/kernel/qaction.cpp +++ b/src/gui/kernel/qaction.cpp @@ -276,7 +276,7 @@ void QActionPrivate::setShortcutEnabled(bool enable, QShortcutMap &map) This enum describes how an action should be placed in the softkey bar. Currently this enum only has an effect on the Symbian platform. - \value NoSoftKey This action should be used as a softkey + \value NoSoftKey This action should not be used as a softkey \value PositiveSoftKey This action is used to describe a softkey with a positive or non-destructive role such as Ok, Select, or Options. \value NegativeSoftKey This action is used to describe a soft ey with a negative or destructive role diff --git a/src/gui/kernel/qwidget.cpp b/src/gui/kernel/qwidget.cpp index 8da415f..de08312 100644 --- a/src/gui/kernel/qwidget.cpp +++ b/src/gui/kernel/qwidget.cpp @@ -1355,6 +1355,8 @@ void QWidget::create(WId window, bool initializeWindow, bool destroyOldWindow) d->setWindowIcon_sys(true); if (isWindow() && !d->topData()->iconText.isEmpty()) d->setWindowIconText_helper(d->topData()->iconText); + if (isWindow() && !d->topData()->caption.isEmpty()) + d->setWindowTitle_helper(d->topData()->caption); if (windowType() != Qt::Desktop) { d->updateSystemBackground(); @@ -5677,9 +5679,8 @@ QString qt_setWindowTitle_helperHelper(const QString &title, const QWidget *widg void QWidgetPrivate::setWindowTitle_helper(const QString &title) { Q_Q(QWidget); - if (!q->testAttribute(Qt::WA_WState_Created)) - createWinId(); - setWindowTitle_sys(qt_setWindowTitle_helperHelper(title, q)); + if (q->testAttribute(Qt::WA_WState_Created)) + setWindowTitle_sys(qt_setWindowTitle_helperHelper(title, q)); } void QWidgetPrivate::setWindowIconText_helper(const QString &title) diff --git a/src/gui/kernel/qwidget_s60.cpp b/src/gui/kernel/qwidget_s60.cpp index 8ce5001..abf5ba5 100644 --- a/src/gui/kernel/qwidget_s60.cpp +++ b/src/gui/kernel/qwidget_s60.cpp @@ -550,8 +550,13 @@ void QWidgetPrivate::raise_sys() Q_Q(QWidget); Q_ASSERT(q->testAttribute(Qt::WA_WState_Created)); - if (q->internalWinId()) + if (q->internalWinId()) { q->internalWinId()->DrawableWindow()->SetOrdinalPosition(0); + + // If toplevel widget, raise app to foreground + if (q->isWindow()) + S60->wsSession().SetWindowGroupOrdinalPosition(S60->windowGroup().Identifier(), 0); + } } void QWidgetPrivate::lower_sys() diff --git a/src/gui/kernel/qwidget_wince.cpp b/src/gui/kernel/qwidget_wince.cpp index 4a0d30c..2fe69e4 100644 --- a/src/gui/kernel/qwidget_wince.cpp +++ b/src/gui/kernel/qwidget_wince.cpp @@ -474,7 +474,7 @@ void QWidget::setWindowState(Qt::WindowStates newstate) int normal = SW_SHOWNOACTIVATE; if ((oldstate & Qt::WindowMinimized) && !(newstate & Qt::WindowMinimized)) - newstate |= Qt::WindowActive; + newstate |= Qt::WindowActive; if (newstate & Qt::WindowActive) normal = SW_SHOWNORMAL; if (isWindow()) { @@ -490,13 +490,13 @@ void QWidget::setWindowState(Qt::WindowStates newstate) d->topData()->normalGeometry = geometry(); } if ((oldstate & Qt::WindowMaximized) != (newstate & Qt::WindowMaximized)) { - if (!(newstate & Qt::WindowMaximized)) { + if (!(newstate & Qt::WindowMaximized)) { int style = GetWindowLong(internalWinId(), GWL_STYLE) | WS_BORDER | WS_POPUP | WS_CAPTION; SetWindowLong(internalWinId(), GWL_STYLE, style); SetWindowLong(internalWinId(), GWL_EXSTYLE, GetWindowLong (internalWinId(), GWL_EXSTYLE) & ~ WS_EX_NODRAG); } - if (isVisible() && newstate & Qt::WindowMaximized) - qt_wince_maximize(this); + if (isVisible() && newstate & Qt::WindowMaximized) + qt_wince_maximize(this); if (isVisible() && !(newstate & Qt::WindowMinimized)) { ShowWindow(internalWinId(), (newstate & Qt::WindowMaximized) ? max : normal); if (!(newstate & Qt::WindowFullScreen)) { @@ -558,18 +558,10 @@ void QWidget::setWindowState(Qt::WindowStates newstate) else if (newstate & Qt::WindowMaximized) { ShowWindow(internalWinId(), max); qt_wince_maximize(this); + } else { + ShowWindow(internalWinId(), normal); } } - if ((newstate & Qt::WindowMaximized) && !(newstate & Qt::WindowFullScreen)) { - QRect r = d->topData()->normalGeometry; -#ifdef Q_WS_WINCE_WM - if (!inherits("QDialog") && !inherits("QMdiArea") && !isVisible()) { - d->data.crect.setRect(0, 0, -1, -1); - } -#else - qt_wince_maximize(this); -#endif - } } data->window_state = newstate; QWindowStateChangeEvent e(oldstate); diff --git a/src/gui/kernel/qwidget_x11.cpp b/src/gui/kernel/qwidget_x11.cpp index 283dfb2..663178f 100644 --- a/src/gui/kernel/qwidget_x11.cpp +++ b/src/gui/kernel/qwidget_x11.cpp @@ -518,14 +518,18 @@ void QWidgetPrivate::create_sys(WId window, bool initializeWindow, bool destroyO if (!window) initializeWindow = true; + QX11Info *parentXinfo = parentWidget ? &parentWidget->d_func()->xinfo : 0; + if (desktop && qt_x11_create_desktop_on_screen >= 0 && qt_x11_create_desktop_on_screen != xinfo.screen()) { // desktop on a certain screen other than the default requested QX11InfoData *xd = &X11->screens[qt_x11_create_desktop_on_screen]; xinfo.setX11Data(xd); - } else if (parentWidget && parentWidget->d_func()->xinfo.screen() != xinfo.screen()) { - xinfo = parentWidget->d_func()->xinfo; + } else if (parentXinfo && (parentXinfo->screen() != xinfo.screen() + || parentXinfo->visual() != xinfo.visual())) + { + xinfo = *parentXinfo; } //get display, screen number, root window and desktop geometry for @@ -920,6 +924,43 @@ void QWidgetPrivate::create_sys(WId window, bool initializeWindow, bool destroyO #endif } +static void qt_x11_recreateWidget(QWidget *widget) +{ + if (widget->inherits("QGLWidget")) { + // We send QGLWidgets a ParentChange event which causes them to + // recreate their GL context, which in turn causes them to choose + // their visual again. Now that WA_TranslucentBackground is set, + // QGLContext::chooseVisual will select an ARGB visual. + QEvent e(QEvent::ParentChange); + QApplication::sendEvent(widget, &e); + } else { + // For regular widgets, reparent them with their parent which + // also triggers a recreation of the native window + QPoint pos = widget->pos(); + bool visible = widget->isVisible(); + if (visible) + widget->hide(); + + widget->setParent(widget->parentWidget(), widget->windowFlags()); + widget->move(pos); + if (visible) + widget->show(); + } +} + +static void qt_x11_recreateNativeWidgetsRecursive(QWidget *widget) +{ + if (widget->testAttribute(Qt::WA_NativeWindow)) + qt_x11_recreateWidget(widget); + + const QObjectList &children = widget->children(); + for (int i = 0; i < children.size(); ++i) { + QWidget *child = qobject_cast<QWidget*>(children.at(i)); + if (child) + qt_x11_recreateNativeWidgetsRecursive(child); + } +} + void QWidgetPrivate::x11UpdateIsOpaque() { #ifndef QT_NO_XRENDER @@ -930,29 +971,9 @@ void QWidgetPrivate::x11UpdateIsOpaque() bool topLevel = (data.window_flags & Qt::Window); int screen = xinfo.screen(); if (topLevel && X11->use_xrender - && X11->argbVisuals[screen] && xinfo.depth() != 32) { - - if (q->inherits("QGLWidget")) { - // We send QGLWidgets a ParentChange event which causes them to - // recreate their GL context, which in turn causes them to choose - // their visual again. Now that WA_TranslucentBackground is set, - // QGLContext::chooseVisual will select an ARGB visual. - QEvent e(QEvent::ParentChange); - QApplication::sendEvent(q, &e); - } - else { - // For regular widgets, reparent them with their parent which - // also triggers a recreation of the native window - QPoint pos = q->pos(); - bool visible = q->isVisible(); - if (visible) - q->hide(); - - q->setParent(q->parentWidget(), q->windowFlags()); - q->move(pos); - if (visible) - q->show(); - } + && X11->argbVisuals[screen] && xinfo.depth() != 32) + { + qt_x11_recreateNativeWidgetsRecursive(q); } #endif } diff --git a/src/gui/painting/qblendfunctions.cpp b/src/gui/painting/qblendfunctions.cpp index 89adaf5..f8dd424 100644 --- a/src/gui/painting/qblendfunctions.cpp +++ b/src/gui/painting/qblendfunctions.cpp @@ -374,9 +374,9 @@ template <typename T> void qt_blend_argb24_on_rgb16(uchar *destPixels, int dbpl, const uchar *src = srcPixels + y * sbpl; const uchar *srcEnd = src + srcOffset; while (src < srcEnd) { -#if defined(QT_ARCH_ARM) || defined(QT_ARCH_POWERPC) || defined(QT_ARCH_SH) || defined(QT_ARCH_AVR32) || (defined(QT_ARCH_WINDOWSCE) && !defined(_X86_)) +#if defined(QT_ARCH_ARM) || defined(QT_ARCH_POWERPC) || defined(QT_ARCH_SH) || defined(QT_ARCH_AVR32) || (defined(QT_ARCH_WINDOWSCE) && !defined(_X86_)) || (defined(QT_ARCH_SPARC) && defined(Q_CC_GNU)) // non-16-bit aligned memory access is not possible on PowerPC, - // ARM <v6 (QT_ARCH_ARMV6) & SH & AVR32 + // ARM <v6 (QT_ARCH_ARMV6) & SH & AVR32 & SPARC w/GCC quint16 spix = (quint16(src[2])<<8) + src[1]; #else quint16 spix = *(quint16 *) (src + 1); diff --git a/src/gui/painting/qpaintengine_raster.cpp b/src/gui/painting/qpaintengine_raster.cpp index 240403d..fab2d8d 100644 --- a/src/gui/painting/qpaintengine_raster.cpp +++ b/src/gui/painting/qpaintengine_raster.cpp @@ -2376,6 +2376,7 @@ void QRasterPaintEngine::drawPixmap(const QPointF &pos, const QPixmap &pixmap) Q_D(QRasterPaintEngine); QRasterPaintEngineState *s = state(); if (s->matrix.type() <= QTransform::TxTranslate) { + ensurePen(); drawBitmap(pos + QPointF(s->matrix.dx(), s->matrix.dy()), image, &s->penData); } else { drawImage(pos, d->rasterBuffer->colorizeBitmap(image, s->pen.color())); @@ -2389,6 +2390,7 @@ void QRasterPaintEngine::drawPixmap(const QPointF &pos, const QPixmap &pixmap) Q_D(QRasterPaintEngine); QRasterPaintEngineState *s = state(); if (s->matrix.type() <= QTransform::TxTranslate) { + ensurePen(); drawBitmap(pos + QPointF(s->matrix.dx(), s->matrix.dy()), image, &s->penData); } else { drawImage(pos, d->rasterBuffer->colorizeBitmap(image, s->pen.color())); diff --git a/src/gui/painting/qpainter.cpp b/src/gui/painting/qpainter.cpp index f271af9..cddad7d 100644 --- a/src/gui/painting/qpainter.cpp +++ b/src/gui/painting/qpainter.cpp @@ -1608,9 +1608,21 @@ void QPainter::restore() \warning A paint device can only be painted by one painter at a time. + \warning Painting on a QImage with the format + QImage::Format_Indexed8 is not supported. + \sa end(), QPainter() */ +static inline void qt_cleanup_painter_state(QPainterPrivate *d) +{ + d->states.clear(); + delete d->state; + d->state = 0; + d->engine = 0; + d->device = 0; +} + bool QPainter::begin(QPaintDevice *pd) { Q_ASSERT(pd); @@ -1656,15 +1668,21 @@ bool QPainter::begin(QPaintDevice *pd) printf("QPainter::begin(), device=%p, type=%d\n", pd, pd->devType()); #endif - - d->device = pd; if (pd->devType() == QInternal::Pixmap) static_cast<QPixmap *>(pd)->detach(); else if (pd->devType() == QInternal::Image) static_cast<QImage *>(pd)->detach(); d->engine = pd->paintEngine(); - d->extended = d->engine && d->engine->isExtended() ? static_cast<QPaintEngineEx *>(d->engine) : 0; + + if (!d->engine) { + qWarning("QPainter::begin: Paint device returned engine == 0, type: %d", pd->devType()); + return false; + } + + d->device = pd; + + d->extended = d->engine->isExtended() ? static_cast<QPaintEngineEx *>(d->engine) : 0; if (d->emulationEngine) d->emulationEngine->real_engine = d->extended; @@ -1677,11 +1695,6 @@ bool QPainter::begin(QPaintDevice *pd) d->state->redirectionMatrix.translate(-redirectionOffset.x(), -redirectionOffset.y()); d->state->brushOrigin = QPointF(); - if (!d->engine) { - qWarning("QPainter::begin: Paint device returned engine == 0, type: %d", pd->devType()); - return false; - } - // Slip a painter state into the engine before we do any other operations if (d->extended) d->extended->setState(d->state); @@ -1700,8 +1713,7 @@ bool QPainter::begin(QPaintDevice *pd) && !paintOutsidePaintEvent && !inPaintEvent) { qWarning("QPainter::begin: Widget painting can only begin as a " "result of a paintEvent"); - d->engine = 0; - d->device = 0; + qt_cleanup_painter_state(d); return false; } @@ -1719,8 +1731,7 @@ bool QPainter::begin(QPaintDevice *pd) Q_ASSERT(pm); if (pm->isNull()) { qWarning("QPainter::begin: Cannot paint on a null pixmap"); - d->engine = 0; - d->device = 0; + qt_cleanup_painter_state(d); return false; } @@ -1736,8 +1747,12 @@ bool QPainter::begin(QPaintDevice *pd) Q_ASSERT(img); if (img->isNull()) { qWarning("QPainter::begin: Cannot paint on a null image"); - d->engine = 0; - d->device = 0; + qt_cleanup_painter_state(d); + return false; + } else if (img->format() == QImage::Format_Indexed8) { + // Painting on indexed8 images is not supported. + qWarning("QPainter::begin: Cannot paint on an image with the QImage::Format_Indexed8 format"); + qt_cleanup_painter_state(d); return false; } if (img->depth() == 1) { @@ -1760,12 +1775,8 @@ bool QPainter::begin(QPaintDevice *pd) if (d->engine->isActive()) { end(); } else { - d->states.clear(); - delete d->state; - d->state = 0; + qt_cleanup_painter_state(d); } - d->engine = 0; - d->device = 0; return false; } else { d->engine->setActive(begun); @@ -1828,10 +1839,7 @@ bool QPainter::end() if (!d->engine) { qWarning("QPainter::end: Painter not active, aborted"); - d->states.clear(); - delete d->state; - d->state = 0; - d->device = 0; + qt_cleanup_painter_state(d); return false; } @@ -1862,8 +1870,6 @@ bool QPainter::end() delete d->engine; } - d->engine = 0; - if (d->emulationEngine) { delete d->emulationEngine; d->emulationEngine = 0; @@ -1873,11 +1879,8 @@ bool QPainter::end() d->extended = 0; } - d->states.clear(); - delete d->state; - d->state = 0; + qt_cleanup_painter_state(d); - d->device = 0; return ended; } @@ -2051,8 +2054,7 @@ QPoint QPainter::brushOrigin() const Sets the brush origin to \a position. The brush origin specifies the (0, 0) coordinate of the painter's - brush. This setting only applies to pattern brushes and pixmap - brushes. + brush. Note that while the brushOrigin() was necessary to adopt the parent's background for a widget in Qt 3, this is no longer the diff --git a/src/gui/painting/qrasterizer.cpp b/src/gui/painting/qrasterizer.cpp index 66d0c9d..b602690 100644 --- a/src/gui/painting/qrasterizer.cpp +++ b/src/gui/painting/qrasterizer.cpp @@ -310,7 +310,7 @@ struct QBoolToType template <typename T> void qScanConvert(QScanConverter &d, T allVertical) { - qSort(d.m_lines.data(), d.m_lines.data() + d.m_lines.size(), topOrder); + qSort(d.m_lines.data(), d.m_lines.data() + d.m_lines.size(), QT_PREPEND_NAMESPACE(topOrder)); int line = 0; for (int y = d.m_lines.first().top; y <= d.m_bottom; ++y) { for (; line < d.m_lines.size() && d.m_lines.at(line).top == y; ++line) { @@ -319,7 +319,7 @@ void qScanConvert(QScanConverter &d, T allVertical) QScanConverter::Line *l = &d.m_lines.at(line); d.m_active.resize(d.m_active.size() + 1); int j; - for (j = d.m_active.size() - 2; j >= 0 && xOrder(l, d.m_active.at(j)); --j) + for (j = d.m_active.size() - 2; j >= 0 && QT_PREPEND_NAMESPACE(xOrder)(l, d.m_active.at(j)); --j) d.m_active.at(j+1) = d.m_active.at(j); d.m_active.at(j+1) = l; } else { @@ -334,7 +334,7 @@ void qScanConvert(QScanConverter &d, T allVertical) for (int i = 1; i < numActive; ++i) { QScanConverter::Line *l = d.m_active.at(i); int j; - for (j = i-1; j >= 0 && xOrder(l, d.m_active.at(j)); --j) + for (j = i-1; j >= 0 && QT_PREPEND_NAMESPACE(xOrder)(l, d.m_active.at(j)); --j) d.m_active.at(j+1) = d.m_active.at(j); d.m_active.at(j+1) = l; } diff --git a/src/gui/painting/qstroker.cpp b/src/gui/painting/qstroker.cpp index 9063945..c57b3c1 100644 --- a/src/gui/painting/qstroker.cpp +++ b/src/gui/painting/qstroker.cpp @@ -969,13 +969,31 @@ QPointF qt_curves_for_arc(const QRectF &rect, qreal startAngle, qreal sweepLengt } +static inline void qdashstroker_moveTo(qfixed x, qfixed y, void *data) { + ((QStroker *) data)->moveTo(x, y); +} + +static inline void qdashstroker_lineTo(qfixed x, qfixed y, void *data) { + ((QStroker *) data)->lineTo(x, y); +} + +static inline void qdashstroker_cubicTo(qfixed, qfixed, qfixed, qfixed, qfixed, qfixed, void *) { + Q_ASSERT(0); +// ((QStroker *) data)->cubicTo(c1x, c1y, c2x, c2y, ex, ey); +} + + /******************************************************************************* * QDashStroker members */ QDashStroker::QDashStroker(QStroker *stroker) - : m_stroker(stroker), m_dashOffset(0) + : m_stroker(stroker), m_dashOffset(0), m_stroke_width(1), m_miter_limit(1) { - + if (m_stroker) { + setMoveToHook(qdashstroker_moveTo); + setLineToHook(qdashstroker_lineTo); + setCubicToHook(qdashstroker_cubicTo); + } } QVector<qfixed> QDashStroker::patternForStyle(Qt::PenStyle style) @@ -1012,10 +1030,16 @@ void QDashStroker::processCurrentSubpath() int dashCount = qMin(m_dashPattern.size(), 32); qfixed dashes[32]; + if (m_stroker) { + m_customData = m_stroker; + m_stroke_width = m_stroker->strokeWidth(); + m_miter_limit = m_stroker->miterLimit(); + } + qreal longestLength = 0; qreal sumLength = 0; for (int i=0; i<dashCount; ++i) { - dashes[i] = qMax(m_dashPattern.at(i), qreal(0)) * m_stroker->strokeWidth(); + dashes[i] = qMax(m_dashPattern.at(i), qreal(0)) * m_stroke_width; sumLength += dashes[i]; if (dashes[i] > longestLength) longestLength = dashes[i]; @@ -1031,7 +1055,7 @@ void QDashStroker::processCurrentSubpath() int idash = 0; // Index to current dash qreal pos = 0; // The position on the curve, 0 <= pos <= path.length qreal elen = 0; // element length - qreal doffset = m_dashOffset * m_stroker->strokeWidth(); + qreal doffset = m_dashOffset * m_stroke_width; // make sure doffset is in range [0..sumLength) doffset -= qFloor(doffset / sumLength) * sumLength; @@ -1056,7 +1080,7 @@ void QDashStroker::processCurrentSubpath() qfixed2d line_to_pos; // Pad to avoid clipping the borders of thick pens. - qfixed padding = qt_real_to_fixed(qMax(m_stroker->strokeWidth(), m_stroker->miterLimit()) * longestLength); + qfixed padding = qt_real_to_fixed(qMax(m_stroke_width, m_miter_limit) * longestLength); qfixed2d clip_tl = { qt_real_to_fixed(m_clip_rect.left()) - padding, qt_real_to_fixed(m_clip_rect.top()) - padding }; qfixed2d clip_br = { qt_real_to_fixed(m_clip_rect.right()) + padding , @@ -1108,7 +1132,7 @@ void QDashStroker::processCurrentSubpath() // continue the current dash, without starting a // new subpath. if (!has_offset || !hasMoveTo) { - m_stroker->moveTo(move_to_pos.x, move_to_pos.y); + emitMoveTo(move_to_pos.x, move_to_pos.y); hasMoveTo = true; } @@ -1120,7 +1144,7 @@ void QDashStroker::processCurrentSubpath() || (line_to_pos.x > clip_tl.x && line_to_pos.x < clip_br.x && line_to_pos.y > clip_tl.y && line_to_pos.y < clip_br.y)) { - m_stroker->lineTo(line_to_pos.x, line_to_pos.y); + emitLineTo(line_to_pos.x, line_to_pos.y); } } else { move_to_pos.x = qt_real_to_fixed(p2.x()); @@ -1134,6 +1158,7 @@ void QDashStroker::processCurrentSubpath() estart = estop; prev = e; } + } QT_END_NAMESPACE diff --git a/src/gui/painting/qstroker_p.h b/src/gui/painting/qstroker_p.h index d33eeb4..a10ebd9 100644 --- a/src/gui/painting/qstroker_p.h +++ b/src/gui/painting/qstroker_p.h @@ -171,7 +171,6 @@ protected: QRectF m_clip_rect; -private: void *m_customData; qStrokerMoveToHook m_moveTo; qStrokerLineToHook m_lineTo; @@ -258,12 +257,18 @@ public: virtual void begin(void *data); virtual void end(); + inline void setStrokeWidth(qreal width) { m_stroke_width = width; } + inline void setMiterLimit(qreal limit) { m_miter_limit = limit; } + protected: virtual void processCurrentSubpath(); QStroker *m_stroker; QVector<qfixed> m_dashPattern; qreal m_dashOffset; + + qreal m_stroke_width; + qreal m_miter_limit; }; @@ -361,16 +366,16 @@ inline void QStroker::emitCubicTo(qfixed c1x, qfixed c1y, */ inline void QDashStroker::begin(void *data) { - Q_ASSERT(m_stroker); - m_stroker->begin(data); + if (m_stroker) + m_stroker->begin(data); QStrokerOps::begin(data); } inline void QDashStroker::end() { - Q_ASSERT(m_stroker); QStrokerOps::end(); - m_stroker->end(); + if (m_stroker) + m_stroker->end(); } QT_END_NAMESPACE diff --git a/src/gui/painting/qtextureglyphcache.cpp b/src/gui/painting/qtextureglyphcache.cpp index 25b6aba..9e5707d 100644 --- a/src/gui/painting/qtextureglyphcache.cpp +++ b/src/gui/painting/qtextureglyphcache.cpp @@ -230,7 +230,14 @@ void QImageTextureGlyphCache::createTextureData(int width, int height) int QImageTextureGlyphCache::glyphMargin() const { #ifdef Q_WS_MAC + +#ifdef QT_MAC_USE_COCOA + // For cocoa the margin is built into the glyph it seems.. + return 0; +#else return 2; +#endif + #else return m_type == QFontEngineGlyphCache::Raster_RGBMask ? 2 : 0; #endif diff --git a/src/gui/styles/qwindowsmobilestyle.cpp b/src/gui/styles/qwindowsmobilestyle.cpp index d27b1ec..a617102 100644 --- a/src/gui/styles/qwindowsmobilestyle.cpp +++ b/src/gui/styles/qwindowsmobilestyle.cpp @@ -6003,7 +6003,7 @@ void QWindowsMobileStyle::drawComplexControl(ComplexControl control, const QStyl } painter->restore(); break; -#endif // QT_NO_SLIDER +#endif // QT_NO_SCROLLBAR case CC_ToolButton: if (const QStyleOptionToolButton *toolbutton = qstyleoption_cast<const QStyleOptionToolButton *>(option)) { diff --git a/src/gui/text/qfontengine_mac.mm b/src/gui/text/qfontengine_mac.mm index 758d8af..d11083f 100644 --- a/src/gui/text/qfontengine_mac.mm +++ b/src/gui/text/qfontengine_mac.mm @@ -119,6 +119,28 @@ OSStatus QMacFontPath::closePath(void *data) } + +void qmacfontengine_gamma_correct(QImage *image) +{ + extern uchar qt_pow_rgb_gamma[256]; + + // gamma correct the pixels back to linear color space... + int h = image->height(); + int w = image->width(); + + for (int y=0; y<h; ++y) { + uint *pixels = (uint *) image->scanLine(y); + for (int x=0; x<w; ++x) { + uint p = pixels[x]; + uint r = qt_pow_rgb_gamma[qRed(p)]; + uint g = qt_pow_rgb_gamma[qGreen(p)]; + uint b = qt_pow_rgb_gamma[qBlue(p)]; + pixels[x] = (r << 16) | (g << 8) | b | 0xff000000; + } + } +} + + #if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5 QCoreTextFontEngineMulti::QCoreTextFontEngineMulti(const ATSFontFamilyRef &, const ATSFontRef &atsFontRef, const QFontDef &fontDef, bool kerning) : QFontEngineMulti(0) @@ -534,7 +556,7 @@ void QCoreTextFontEngine::addGlyphsToPath(glyph_t *glyphs, QFixedPoint *position } } -QImage QCoreTextFontEngine::alphaMapForGlyph(glyph_t glyph) +QImage QCoreTextFontEngine::imageForGlyph(glyph_t glyph, int margin, bool aa) { const glyph_metrics_t br = boundingBox(glyph); QImage im(qRound(br.width)+2, qRound(br.height)+2, QImage::Format_RGB32); @@ -549,9 +571,10 @@ QImage QCoreTextFontEngine::alphaMapForGlyph(glyph_t glyph) 8, im.bytesPerLine(), colorspace, cgflags); CGContextSetFontSize(ctx, fontDef.pixelSize); - CGContextSetShouldAntialias(ctx, fontDef.pointSize > qt_antialiasing_threshold - && !(fontDef.styleStrategy & QFont::NoAntialias)); - CGContextSetShouldSmoothFonts(ctx, false); + CGContextSetShouldAntialias(ctx, aa || + (fontDef.pointSize > qt_antialiasing_threshold + && !(fontDef.styleStrategy & QFont::NoAntialias))); + CGContextSetShouldSmoothFonts(ctx, aa); CGAffineTransform oldTextMatrix = CGContextGetTextMatrix(ctx); CGAffineTransform cgMatrix = CGAffineTransformMake(1, 0, 0, 1, 0, 0); @@ -586,6 +609,13 @@ QImage QCoreTextFontEngine::alphaMapForGlyph(glyph_t glyph) CGContextRelease(ctx); + return im; +} + +QImage QCoreTextFontEngine::alphaMapForGlyph(glyph_t glyph) +{ + QImage im = imageForGlyph(glyph, 0, false); + QImage indexed(im.width(), im.height(), QImage::Format_Indexed8); QVector<QRgb> colors(256); for (int i=0; i<256; ++i) @@ -605,6 +635,16 @@ QImage QCoreTextFontEngine::alphaMapForGlyph(glyph_t glyph) return indexed; } +QImage QCoreTextFontEngine::alphaRGBMapForGlyph(glyph_t glyph, int margin, const QTransform &x) +{ + if (x.type() >= QTransform::TxScale) + return QFontEngine::alphaRGBMapForGlyph(glyph, margin, x); + + QImage im = imageForGlyph(glyph, margin, true); + qmacfontengine_gamma_correct(&im); + return im; +} + void QCoreTextFontEngine::recalcAdvances(int numGlyphs, QGlyphLayout *glyphs, QTextEngine::ShaperFlags flags) const { Q_ASSERT(false); @@ -1505,19 +1545,7 @@ QImage QFontEngineMac::alphaRGBMapForGlyph(glyph_t glyph, int margin, const QTra im = im.transformed(t); } - extern uchar qt_pow_rgb_gamma[256]; - - // gamma correct the pixels back to linear color space... - for (int y=0; y<im.height(); ++y) { - uint *pixels = (uint *) im.scanLine(y); - for (int x=0; x<im.width(); ++x) { - uint p = pixels[x]; - uint r = qt_pow_rgb_gamma[qRed(p)]; - uint g = qt_pow_rgb_gamma[qGreen(p)]; - uint b = qt_pow_rgb_gamma[qBlue(p)]; - pixels[x] = (r << 16) | (g << 8) | b | 0xff000000; - } - } + qmacfontengine_gamma_correct(&im); return im; } diff --git a/src/gui/text/qfontengine_p.h b/src/gui/text/qfontengine_p.h index 50124fa..728c344 100644 --- a/src/gui/text/qfontengine_p.h +++ b/src/gui/text/qfontengine_p.h @@ -448,12 +448,13 @@ public: virtual bool getSfntTableData(uint /*tag*/, uchar * /*buffer*/, uint * /*length*/) const; virtual void getUnscaledGlyph(glyph_t glyph, QPainterPath *path, glyph_metrics_t *metrics); virtual QImage alphaMapForGlyph(glyph_t); + virtual QImage alphaRGBMapForGlyph(glyph_t, int margin, const QTransform &t); virtual qreal minRightBearing() const; virtual qreal minLeftBearing() const; - private: + QImage imageForGlyph(glyph_t glyph, int margin, bool colorful); CTFontRef ctfont; CGFontRef cgFont; QCoreTextFontEngineMulti *parentEngine; |