diff options
author | A-Team <ateam@pad.test.qt.nokia.com> | 2010-09-24 22:00:19 (GMT) |
---|---|---|
committer | A-Team <ateam@pad.test.qt.nokia.com> | 2010-09-24 22:00:19 (GMT) |
commit | 81d25b1c69dc186eaa3d3993e74ae132cc8f582a (patch) | |
tree | 7034202e9b2108c2d0ced275448e8ececf816612 /src/gui | |
parent | 84d278501a19eaccf9a77cccd95ca5d17a2dcd2b (diff) | |
parent | f28d3e2f6c09abe7629779a8b10f3caa9007c468 (diff) | |
download | Qt-81d25b1c69dc186eaa3d3993e74ae132cc8f582a.zip Qt-81d25b1c69dc186eaa3d3993e74ae132cc8f582a.tar.gz Qt-81d25b1c69dc186eaa3d3993e74ae132cc8f582a.tar.bz2 |
Merge branch '4.7-upstream' into 4.7-doc
Diffstat (limited to 'src/gui')
-rw-r--r-- | src/gui/graphicsview/qgraphicsscene.cpp | 126 | ||||
-rw-r--r-- | src/gui/graphicsview/qgraphicsview.cpp | 3 | ||||
-rw-r--r-- | src/gui/image/qpixmap.cpp | 43 | ||||
-rw-r--r-- | src/gui/image/qpixmap_x11.cpp | 3 | ||||
-rw-r--r-- | src/gui/itemviews/qtreeview.cpp | 4 | ||||
-rw-r--r-- | src/gui/kernel/qapplication.cpp | 9 | ||||
-rw-r--r-- | src/gui/kernel/qdnd_win.cpp | 12 | ||||
-rw-r--r-- | src/gui/painting/qrasterizer.cpp | 180 | ||||
-rw-r--r-- | src/gui/styles/qstylehelper_p.h | 2 | ||||
-rw-r--r-- | src/gui/text/qtextcontrol.cpp | 6 | ||||
-rw-r--r-- | src/gui/widgets/qlabel.cpp | 27 | ||||
-rw-r--r-- | src/gui/widgets/qlabel_p.h | 1 |
12 files changed, 246 insertions, 170 deletions
diff --git a/src/gui/graphicsview/qgraphicsscene.cpp b/src/gui/graphicsview/qgraphicsscene.cpp index 54fdf3f..8dc15bf 100644 --- a/src/gui/graphicsview/qgraphicsscene.cpp +++ b/src/gui/graphicsview/qgraphicsscene.cpp @@ -4814,6 +4814,27 @@ void QGraphicsScenePrivate::drawSubtreeRecursive(QGraphicsItem *item, QPainter * } } +static inline void setClip(QPainter *painter, QGraphicsItem *item) +{ + painter->save(); + QRectF clipRect; + const QPainterPath clipPath(item->shape()); + if (QPathClipper::pathToRect(clipPath, &clipRect)) + painter->setClipRect(clipRect, Qt::IntersectClip); + else + painter->setClipPath(clipPath, Qt::IntersectClip); +} + +static inline void setWorldTransform(QPainter *painter, const QTransform *const transformPtr, + const QTransform *effectTransform) +{ + Q_ASSERT(transformPtr); + if (effectTransform) + painter->setWorldTransform(*transformPtr * *effectTransform); + else + painter->setWorldTransform(*transformPtr); +} + void QGraphicsScenePrivate::draw(QGraphicsItem *item, QPainter *painter, const QTransform *const viewTransform, const QTransform *const transformPtr, QRegion *exposedRegion, QWidget *widget, qreal opacity, const QTransform *effectTransform, @@ -4822,36 +4843,37 @@ void QGraphicsScenePrivate::draw(QGraphicsItem *item, QPainter *painter, const Q const bool itemIsFullyTransparent = QGraphicsItemPrivate::isOpacityNull(opacity); const bool itemClipsChildrenToShape = (item->d_ptr->flags & QGraphicsItem::ItemClipsChildrenToShape); const bool itemHasChildren = !item->d_ptr->children.isEmpty(); + bool setChildClip = itemClipsChildrenToShape; + bool itemHasChildrenStackedBehind = false; int i = 0; if (itemHasChildren) { + if (itemClipsChildrenToShape) + setWorldTransform(painter, transformPtr, effectTransform); + item->d_ptr->ensureSortedChildren(); + // Items with the 'ItemStacksBehindParent' flag are put in front of the list + // so all we have to do is to check the first item. + itemHasChildrenStackedBehind = (item->d_ptr->children.at(0)->d_ptr->flags + & QGraphicsItem::ItemStacksBehindParent); - if (itemClipsChildrenToShape) { - painter->save(); - Q_ASSERT(transformPtr); - if (effectTransform) - painter->setWorldTransform(*transformPtr * *effectTransform); - else - painter->setWorldTransform(*transformPtr); - QRectF clipRect; - const QPainterPath clipPath(item->shape()); - if (QPathClipper::pathToRect(clipPath, &clipRect)) - painter->setClipRect(clipRect, Qt::IntersectClip); - else - painter->setClipPath(clipPath, Qt::IntersectClip); - } + if (itemHasChildrenStackedBehind) { + if (itemClipsChildrenToShape) { + setClip(painter, item); + setChildClip = false; + } - // Draw children behind - for (i = 0; i < item->d_ptr->children.size(); ++i) { - QGraphicsItem *child = item->d_ptr->children.at(i); - if (wasDirtyParentSceneTransform) - child->d_ptr->dirtySceneTransform = 1; - if (!(child->d_ptr->flags & QGraphicsItem::ItemStacksBehindParent)) - break; - if (itemIsFullyTransparent && !(child->d_ptr->flags & QGraphicsItem::ItemIgnoresParentOpacity)) - continue; - drawSubtreeRecursive(child, painter, viewTransform, exposedRegion, widget, opacity, effectTransform); + // Draw children behind + for (i = 0; i < item->d_ptr->children.size(); ++i) { + QGraphicsItem *child = item->d_ptr->children.at(i); + if (wasDirtyParentSceneTransform) + child->d_ptr->dirtySceneTransform = 1; + if (!(child->d_ptr->flags & QGraphicsItem::ItemStacksBehindParent)) + break; + if (itemIsFullyTransparent && !(child->d_ptr->flags & QGraphicsItem::ItemIgnoresParentOpacity)) + continue; + drawSubtreeRecursive(child, painter, viewTransform, exposedRegion, widget, opacity, effectTransform); + } } } @@ -4864,38 +4886,50 @@ void QGraphicsScenePrivate::draw(QGraphicsItem *item, QPainter *painter, const Q ? *exposedRegion : QRegion(), exposedRegion == 0); const bool itemClipsToShape = item->d_ptr->flags & QGraphicsItem::ItemClipsToShape; - const bool savePainter = itemClipsToShape || painterStateProtection; - if (savePainter) - painter->save(); + bool restorePainterClip = false; if (!itemHasChildren || !itemClipsChildrenToShape) { - if (effectTransform) - painter->setWorldTransform(*transformPtr * *effectTransform); - else - painter->setWorldTransform(*transformPtr); + // Item does not have children or clip children to shape. + setWorldTransform(painter, transformPtr, effectTransform); + if ((restorePainterClip = itemClipsToShape)) + setClip(painter, item); + } else if (itemHasChildrenStackedBehind){ + // Item clips children to shape and has children stacked behind, which means + // the painter is already clipped to the item's shape. + if (itemClipsToShape) { + // The clip is already correct. Ensure correct world transform. + setWorldTransform(painter, transformPtr, effectTransform); + } else { + // Remove clip (this also ensures correct world transform). + painter->restore(); + setChildClip = true; + } + } else if (itemClipsToShape) { + // Item clips children and itself to shape. It does not have hildren stacked + // behind, which means the clip has not yet been set. We set it now and re-use it + // for the children. + setClip(painter, item); + setChildClip = false; } - if (itemClipsToShape) { - QRectF clipRect; - const QPainterPath clipPath(item->shape()); - if (QPathClipper::pathToRect(clipPath, &clipRect)) - painter->setClipRect(clipRect, Qt::IntersectClip); - else - painter->setClipPath(clipPath, Qt::IntersectClip); - } - painter->setOpacity(opacity); + if (painterStateProtection && !restorePainterClip) + painter->save(); + painter->setOpacity(opacity); if (!item->d_ptr->cacheMode && !item->d_ptr->isWidget) item->paint(painter, &styleOptionTmp, widget); else drawItemHelper(item, painter, &styleOptionTmp, widget, painterStateProtection); - if (savePainter) + if (painterStateProtection || restorePainterClip) painter->restore(); } // Draw children in front if (itemHasChildren) { + if (setChildClip) + setClip(painter, item); + for (; i < item->d_ptr->children.size(); ++i) { QGraphicsItem *child = item->d_ptr->children.at(i); if (wasDirtyParentSceneTransform) @@ -4904,11 +4938,11 @@ void QGraphicsScenePrivate::draw(QGraphicsItem *item, QPainter *painter, const Q continue; drawSubtreeRecursive(child, painter, viewTransform, exposedRegion, widget, opacity, effectTransform); } - } - // Restore child clip - if (itemHasChildren && itemClipsChildrenToShape) - painter->restore(); + // Restore child clip + if (itemClipsChildrenToShape) + painter->restore(); + } } void QGraphicsScenePrivate::markDirty(QGraphicsItem *item, const QRectF &rect, bool invalidateChildren, @@ -5271,6 +5305,7 @@ void QGraphicsScene::drawItems(QPainter *painter, if (!d->unpolishedItems.isEmpty()) d->_q_polishItems(); + const qreal opacity = painter->opacity(); QTransform viewTransform = painter->worldTransform(); Q_UNUSED(options); @@ -5304,6 +5339,7 @@ void QGraphicsScene::drawItems(QPainter *painter, topLevelItems.at(i)->d_ptr->itemDiscovered = 0; painter->setWorldTransform(viewTransform); + painter->setOpacity(opacity); } /*! diff --git a/src/gui/graphicsview/qgraphicsview.cpp b/src/gui/graphicsview/qgraphicsview.cpp index c8aca80..a566c8e 100644 --- a/src/gui/graphicsview/qgraphicsview.cpp +++ b/src/gui/graphicsview/qgraphicsview.cpp @@ -3475,7 +3475,8 @@ void QGraphicsView::paintEvent(QPaintEvent *event) // IndirectPainting (the else branch), because in that case we always save() // and restore() in QGraphicsScene::drawItems(). if (!d->scene->d_func()->painterStateProtection) - painter.setWorldTransform(viewTransform); + painter.setOpacity(1.0); + painter.setWorldTransform(viewTransform); } else { // Make sure we don't have unpolished items before we draw if (!d->scene->d_func()->unpolishedItems.isEmpty()) diff --git a/src/gui/image/qpixmap.cpp b/src/gui/image/qpixmap.cpp index 1e502bd..64d8ed2 100644 --- a/src/gui/image/qpixmap.cpp +++ b/src/gui/image/qpixmap.cpp @@ -664,14 +664,19 @@ void QPixmap::resize_helper(const QSize &s) #if defined(Q_WS_X11) if (x11Data && x11Data->x11_mask) { - QX11PixmapData *pmData = static_cast<QX11PixmapData*>(pd); - pmData->x11_mask = (Qt::HANDLE)XCreatePixmap(X11->display, - RootWindow(x11Data->xinfo.display(), - x11Data->xinfo.screen()), - w, h, 1); - GC gc = XCreateGC(X11->display, pmData->x11_mask, 0, 0); - XCopyArea(X11->display, x11Data->x11_mask, pmData->x11_mask, gc, 0, 0, qMin(width(), w), qMin(height(), h), 0, 0); - XFreeGC(X11->display, gc); + QPixmapData *newPd = pm.pixmapData(); + QX11PixmapData *pmData = (newPd && newPd->classId() == QPixmapData::X11Class) + ? static_cast<QX11PixmapData*>(newPd) : 0; + if (pmData) { + pmData->x11_mask = (Qt::HANDLE)XCreatePixmap(X11->display, + RootWindow(x11Data->xinfo.display(), + x11Data->xinfo.screen()), + w, h, 1); + GC gc = XCreateGC(X11->display, pmData->x11_mask, 0, 0); + XCopyArea(X11->display, x11Data->x11_mask, pmData->x11_mask, gc, 0, 0, + qMin(width(), w), qMin(height(), h), 0, 0); + XFreeGC(X11->display, gc); + } } #endif *this = pm; @@ -836,7 +841,7 @@ bool QPixmap::load(const QString &fileName, const char *format, Qt::ImageConvers % HexString<quint64>(info.size()) % HexString<uint>(data ? data->pixelType() : QPixmapData::PixmapType); - // Note: If no extension is provided, we try to match the + // Note: If no extension is provided, we try to match the // file against known plugin extensions if (!info.completeSuffix().isEmpty() && !info.exists()) return false; @@ -1793,13 +1798,27 @@ QPixmap QPixmap::transformed(const QMatrix &matrix, Qt::TransformationMode mode) Returns true if this pixmap has an alpha channel, \e or has a mask, otherwise returns false. - \warning This is potentially an expensive operation. - \sa hasAlphaChannel(), mask() */ bool QPixmap::hasAlpha() const { - return data && (data->hasAlphaChannel() || !data->mask().isNull()); +#if defined(Q_WS_X11) + if (data && data->hasAlphaChannel()) + return true; + QPixmapData *pd = pixmapData(); + if (pd && pd->classId() == QPixmapData::X11Class) { + QX11PixmapData *x11Data = static_cast<QX11PixmapData*>(pd); +#ifndef QT_NO_XRENDER + if (x11Data->picture && x11Data->d == 32) + return true; +#endif + if (x11Data->d == 1 || x11Data->x11_mask) + return true; + } + return false; +#else + return data && data->hasAlphaChannel(); +#endif } /*! diff --git a/src/gui/image/qpixmap_x11.cpp b/src/gui/image/qpixmap_x11.cpp index 3d9c363..01f2c11 100644 --- a/src/gui/image/qpixmap_x11.cpp +++ b/src/gui/image/qpixmap_x11.cpp @@ -1321,7 +1321,6 @@ QBitmap QX11PixmapData::mask() const return mask; } - /*! Sets a mask bitmap. @@ -1549,7 +1548,7 @@ QImage QX11PixmapData::toImage(const QRect &rect) const if (!xiWrapper.xi) return QImage(); - if (canTakeQImageFromXImage(xiWrapper)) + if (!x11_mask && canTakeQImageFromXImage(xiWrapper)) return takeQImageFromXImage(xiWrapper); QImage image = toImage(xiWrapper, rect); diff --git a/src/gui/itemviews/qtreeview.cpp b/src/gui/itemviews/qtreeview.cpp index b797776..40b51fe 100644 --- a/src/gui/itemviews/qtreeview.cpp +++ b/src/gui/itemviews/qtreeview.cpp @@ -3435,6 +3435,10 @@ void QTreeViewPrivate::updateScrollBars() if (!viewportSize.isValid()) viewportSize = QSize(0, 0); + if (viewItems.isEmpty()) { + q->doItemsLayout(); + } + int itemsInViewport = 0; if (uniformRowHeights) { if (defaultItemHeight <= 0) diff --git a/src/gui/kernel/qapplication.cpp b/src/gui/kernel/qapplication.cpp index e6dc623..fdacefc 100644 --- a/src/gui/kernel/qapplication.cpp +++ b/src/gui/kernel/qapplication.cpp @@ -2403,8 +2403,13 @@ static const char *application_menu_strings[] = { }; QString qt_mac_applicationmenu_string(int type) { - return qApp->translate("MAC_APPLICATION_MENU", - application_menu_strings[type]); + QString menuString = QString::fromLatin1(application_menu_strings[type]); + QString translated = qApp->translate("QMenuBar", application_menu_strings[type]); + if (translated != menuString) + return translated; + else + return qApp->translate("MAC_APPLICATION_MENU", + application_menu_strings[type]); } #endif #endif diff --git a/src/gui/kernel/qdnd_win.cpp b/src/gui/kernel/qdnd_win.cpp index a164c2a..7083886 100644 --- a/src/gui/kernel/qdnd_win.cpp +++ b/src/gui/kernel/qdnd_win.cpp @@ -515,7 +515,7 @@ static inline Qt::MouseButtons keystate_to_mousebutton(DWORD grfKeyState) //--------------------------------------------------------------------- // IDropSource Methods //--------------------------------------------------------------------- -STDMETHODIMP +QT_ENSURE_STACK_ALIGNED_FOR_SSE STDMETHODIMP QOleDropSource::QueryContinueDrag(BOOL fEscapePressed, DWORD grfKeyState) { #ifdef QDND_DEBUG @@ -545,7 +545,7 @@ QOleDropSource::QueryContinueDrag(BOOL fEscapePressed, DWORD grfKeyState) } } -STDMETHODIMP +QT_ENSURE_STACK_ALIGNED_FOR_SSE STDMETHODIMP QOleDropSource::GiveFeedback(DWORD dwEffect) { Qt::DropAction action = translateToQDragDropAction(dwEffect); @@ -626,7 +626,7 @@ QOleDropTarget::Release(void) // IDropTarget Methods //--------------------------------------------------------------------- -STDMETHODIMP +QT_ENSURE_STACK_ALIGNED_FOR_SSE STDMETHODIMP QOleDropTarget::DragEnter(LPDATAOBJECT pDataObj, DWORD grfKeyState, POINTL pt, LPDWORD pdwEffect) { #ifdef QDND_DEBUG @@ -688,7 +688,7 @@ void QOleDropTarget::sendDragEnterEvent(QWidget *dragEnterWidget, DWORD grfKeySt } -STDMETHODIMP +QT_ENSURE_STACK_ALIGNED_FOR_SSE STDMETHODIMP QOleDropTarget::DragOver(DWORD grfKeyState, POINTL pt, LPDWORD pdwEffect) { #ifdef QDND_DEBUG @@ -758,7 +758,7 @@ QOleDropTarget::DragOver(DWORD grfKeyState, POINTL pt, LPDWORD pdwEffect) return NOERROR; } -STDMETHODIMP +QT_ENSURE_STACK_ALIGNED_FOR_SSE STDMETHODIMP QOleDropTarget::DragLeave() { #ifdef QDND_DEBUG @@ -785,7 +785,7 @@ QOleDropTarget::DragLeave() #define KEY_STATE_BUTTON_MASK (MK_LBUTTON | MK_MBUTTON | MK_RBUTTON) -STDMETHODIMP +QT_ENSURE_STACK_ALIGNED_FOR_SSE STDMETHODIMP QOleDropTarget::Drop(LPDATAOBJECT /*pDataObj*/, DWORD grfKeyState, POINTL pt, LPDWORD pdwEffect) { #ifdef QDND_DEBUG diff --git a/src/gui/painting/qrasterizer.cpp b/src/gui/painting/qrasterizer.cpp index f8f8afb..4fded1f 100644 --- a/src/gui/painting/qrasterizer.cpp +++ b/src/gui/painting/qrasterizer.cpp @@ -65,6 +65,12 @@ typedef int Q16Dot16; #define COORD_ROUNDING 1 // 0: round up, 1: round down #define COORD_OFFSET 32 // 26.6, 32 is half a pixel +static inline QT_FT_Vector PointToVector(const QPointF &p) +{ + QT_FT_Vector result = { QT_FT_Pos(p.x() * 64), QT_FT_Pos(p.y() * 64) }; + return result; +} + class QSpanBuffer { public: QSpanBuffer(ProcessSpans blend, void *data, const QRect &clipRect) @@ -693,9 +699,9 @@ static Q16Dot16 intersectPixelFP(int x, Q16Dot16 top, Q16Dot16 bottom, Q16Dot16 } } -static inline bool q16Dot16Compare(qreal p1, qreal p2) +static inline bool q26Dot6Compare(qreal p1, qreal p2) { - return FloatToQ16Dot16(p2 - p1) == 0; + return int((p2 - p1) * 64.) == 0; } static inline qreal qFloorF(qreal v) @@ -708,6 +714,12 @@ static inline qreal qFloorF(qreal v) return floor(v); } +static inline QPointF snapTo26Dot6Grid(const QPointF &p) +{ + return QPointF(qFloorF(p.x() * 64) * (1 / qreal(64)), + qFloorF(p.y() * 64) * (1 / qreal(64))); +} + void QRasterizer::rasterizeLine(const QPointF &a, const QPointF &b, qreal width, bool squareCap) { if (a == b || width == 0 || d->clipRect.isEmpty()) @@ -718,17 +730,21 @@ void QRasterizer::rasterizeLine(const QPointF &a, const QPointF &b, qreal width, QPointF pa = a; QPointF pb = b; - QPointF offs = QPointF(qAbs(b.y() - a.y()), qAbs(b.x() - a.x())) * width * 0.5; - if (squareCap) - offs += QPointF(offs.y(), offs.x()); + if (squareCap) { + QPointF delta = pb - pa; + pa -= (0.5f * width) * delta; + pb += (0.5f * width) * delta; + } + + QPointF offs = QPointF(qAbs(b.y() - a.y()), qAbs(b.x() - a.x())) * width * 0.5; const QRectF clip(d->clipRect.topLeft() - offs, d->clipRect.bottomRight() + QPoint(1, 1) + offs); - if (!clip.contains(a) || !clip.contains(b)) { + if (!clip.contains(pa) || !clip.contains(pb)) { qreal t1 = 0; qreal t2 = 1; - const qreal o[2] = { a.x(), a.y() }; - const qreal d[2] = { b.x() - a.x(), b.y() - a.y() }; + const qreal o[2] = { pa.x(), pa.y() }; + const qreal d[2] = { pb.x() - pa.x(), pb.y() - pa.y() }; const qreal low[2] = { clip.left(), clip.top() }; const qreal high[2] = { clip.right(), clip.bottom() }; @@ -751,8 +767,12 @@ void QRasterizer::rasterizeLine(const QPointF &a, const QPointF &b, qreal width, if (t1 >= t2) return; } - pa = a + (b - a) * t1; - pb = a + (b - a) * t2; + + QPointF npa = pa + (pb - pa) * t1; + QPointF npb = pa + (pb - pa) * t2; + + pa = npa; + pb = npb; } if (!d->antialiased) { @@ -763,15 +783,6 @@ void QRasterizer::rasterizeLine(const QPointF &a, const QPointF &b, qreal width, } { - const qreal gridResolution = 64; - const qreal reciprocal = 1 / gridResolution; - - // snap to grid to prevent large slopes - pa.rx() = qFloorF(pa.rx() * gridResolution) * reciprocal; - pa.ry() = qFloorF(pa.ry() * gridResolution) * reciprocal; - pb.rx() = qFloorF(pb.rx() * gridResolution) * reciprocal; - pb.ry() = qFloorF(pb.ry() * gridResolution) * reciprocal; - // old delta const QPointF d0 = a - b; const qreal w0 = d0.x() * d0.x() + d0.y() * d0.y(); @@ -789,7 +800,7 @@ void QRasterizer::rasterizeLine(const QPointF &a, const QPointF &b, qreal width, QSpanBuffer buffer(d->blend, d->data, d->clipRect); - if (q16Dot16Compare(pa.y(), pb.y())) { + if (q26Dot6Compare(pa.y(), pb.y())) { const qreal x = (pa.x() + pb.x()) * 0.5f; const qreal dx = qAbs(pb.x() - pa.x()) * 0.5f; @@ -799,26 +810,16 @@ void QRasterizer::rasterizeLine(const QPointF &a, const QPointF &b, qreal width, pa = QPointF(x, y - dy); pb = QPointF(x, y + dy); - if (squareCap) - width = 1 / width + 1.0f; - else - width = 1 / width; - - squareCap = false; + width = 1 / width; } - if (q16Dot16Compare(pa.x(), pb.x())) { + if (q26Dot6Compare(pa.x(), pb.x())) { if (pa.y() > pb.y()) qSwap(pa, pb); const qreal dy = pb.y() - pa.y(); const qreal halfWidth = 0.5f * width * dy; - if (squareCap) { - pa.ry() -= halfWidth; - pb.ry() += halfWidth; - } - qreal left = pa.x() - halfWidth; qreal right = pa.x() + halfWidth; @@ -828,7 +829,7 @@ void QRasterizer::rasterizeLine(const QPointF &a, const QPointF &b, qreal width, pa.ry() = qBound(qreal(d->clipRect.top()), pa.y(), qreal(d->clipRect.bottom() + 1)); pb.ry() = qBound(qreal(d->clipRect.top()), pb.y(), qreal(d->clipRect.bottom() + 1)); - if (q16Dot16Compare(left, right) || q16Dot16Compare(pa.y(), pb.y())) + if (q26Dot6Compare(left, right) || q26Dot6Compare(pa.y(), pb.y())) return; if (d->antialiased) { @@ -899,11 +900,6 @@ void QRasterizer::rasterizeLine(const QPointF &a, const QPointF &b, qreal width, delta *= 0.5f * width; const QPointF perp(delta.y(), -delta.x()); - if (squareCap) { - pa -= delta; - pb += delta; - } - QPointF top; QPointF left; QPointF right; @@ -921,14 +917,36 @@ void QRasterizer::rasterizeLine(const QPointF &a, const QPointF &b, qreal width, bottom = pb + perp; } + top = snapTo26Dot6Grid(top); + bottom = snapTo26Dot6Grid(bottom); + left = snapTo26Dot6Grid(left); + right = snapTo26Dot6Grid(right); + const qreal topBound = qBound(qreal(d->clipRect.top()), top.y(), qreal(d->clipRect.bottom())); const qreal bottomBound = qBound(qreal(d->clipRect.top()), bottom.y(), qreal(d->clipRect.bottom())); - const qreal leftSlope = (left.x() - top.x()) / (left.y() - top.y()); - const qreal rightSlope = -1.0f / leftSlope; + const QPointF topLeftEdge = left - top; + const QPointF topRightEdge = right - top; + const QPointF bottomLeftEdge = bottom - left; + const QPointF bottomRightEdge = bottom - right; + + const qreal topLeftSlope = topLeftEdge.x() / topLeftEdge.y(); + const qreal bottomLeftSlope = bottomLeftEdge.x() / bottomLeftEdge.y(); + + const qreal topRightSlope = topRightEdge.x() / topRightEdge.y(); + const qreal bottomRightSlope = bottomRightEdge.x() / bottomRightEdge.y(); + + const Q16Dot16 topLeftSlopeFP = FloatToQ16Dot16(topLeftSlope); + const Q16Dot16 topRightSlopeFP = FloatToQ16Dot16(topRightSlope); - const Q16Dot16 leftSlopeFP = FloatToQ16Dot16(leftSlope); - const Q16Dot16 rightSlopeFP = FloatToQ16Dot16(rightSlope); + const Q16Dot16 bottomLeftSlopeFP = FloatToQ16Dot16(bottomLeftSlope); + const Q16Dot16 bottomRightSlopeFP = FloatToQ16Dot16(bottomRightSlope); + + const Q16Dot16 invTopLeftSlopeFP = FloatToQ16Dot16(1 / topLeftSlope); + const Q16Dot16 invTopRightSlopeFP = FloatToQ16Dot16(1 / topRightSlope); + + const Q16Dot16 invBottomLeftSlopeFP = FloatToQ16Dot16(1 / bottomLeftSlope); + const Q16Dot16 invBottomRightSlopeFP = FloatToQ16Dot16(1 / bottomRightSlope); if (d->antialiased) { const Q16Dot16 iTopFP = IntToQ16Dot16(int(topBound)); @@ -936,16 +954,16 @@ void QRasterizer::rasterizeLine(const QPointF &a, const QPointF &b, qreal width, const Q16Dot16 iRightFP = IntToQ16Dot16(int(right.y())); const Q16Dot16 iBottomFP = IntToQ16Dot16(int(bottomBound)); - Q16Dot16 leftIntersectAf = FloatToQ16Dot16(top.x() + (int(topBound) - top.y()) * leftSlope); - Q16Dot16 rightIntersectAf = FloatToQ16Dot16(top.x() + (int(topBound) - top.y()) * rightSlope); + Q16Dot16 leftIntersectAf = FloatToQ16Dot16(top.x() + (int(topBound) - top.y()) * topLeftSlope); + Q16Dot16 rightIntersectAf = FloatToQ16Dot16(top.x() + (int(topBound) - top.y()) * topRightSlope); Q16Dot16 leftIntersectBf = 0; Q16Dot16 rightIntersectBf = 0; if (iLeftFP < iTopFP) - leftIntersectBf = FloatToQ16Dot16(left.x() + (int(topBound) - left.y()) * rightSlope); + leftIntersectBf = FloatToQ16Dot16(left.x() + (int(topBound) - left.y()) * bottomLeftSlope); if (iRightFP < iTopFP) - rightIntersectBf = FloatToQ16Dot16(right.x() + (int(topBound) - right.y()) * leftSlope); + rightIntersectBf = FloatToQ16Dot16(right.x() + (int(topBound) - right.y()) * bottomRightSlope); Q16Dot16 rowTop, rowBottomLeft, rowBottomRight, rowTopLeft, rowTopRight, rowBottom; Q16Dot16 topLeftIntersectAf, topLeftIntersectBf, topRightIntersectAf, topRightIntersectBf; @@ -960,9 +978,9 @@ void QRasterizer::rasterizeLine(const QPointF &a, const QPointF &b, qreal width, rowTop = qMax(iTopFP, yTopFP); topLeftIntersectAf = leftIntersectAf + - Q16Dot16Multiply(leftSlopeFP, rowTop - iTopFP); + Q16Dot16Multiply(topLeftSlopeFP, rowTop - iTopFP); topRightIntersectAf = rightIntersectAf + - Q16Dot16Multiply(rightSlopeFP, rowTop - iTopFP); + Q16Dot16Multiply(topRightSlopeFP, rowTop - iTopFP); Q16Dot16 yFP = iTopFP; while (yFP <= iBottomFP) { @@ -974,30 +992,30 @@ void QRasterizer::rasterizeLine(const QPointF &a, const QPointF &b, qreal width, if (yFP == iLeftFP) { const int y = Q16Dot16ToInt(yFP); - leftIntersectBf = FloatToQ16Dot16(left.x() + (y - left.y()) * rightSlope); - topLeftIntersectBf = leftIntersectBf + Q16Dot16Multiply(rightSlopeFP, rowTopLeft - yFP); - bottomLeftIntersectAf = leftIntersectAf + Q16Dot16Multiply(leftSlopeFP, rowBottomLeft - yFP); + leftIntersectBf = FloatToQ16Dot16(left.x() + (y - left.y()) * bottomLeftSlope); + topLeftIntersectBf = leftIntersectBf + Q16Dot16Multiply(bottomLeftSlopeFP, rowTopLeft - yFP); + bottomLeftIntersectAf = leftIntersectAf + Q16Dot16Multiply(topLeftSlopeFP, rowBottomLeft - yFP); } else { topLeftIntersectBf = leftIntersectBf; - bottomLeftIntersectAf = leftIntersectAf + leftSlopeFP; + bottomLeftIntersectAf = leftIntersectAf + topLeftSlopeFP; } if (yFP == iRightFP) { const int y = Q16Dot16ToInt(yFP); - rightIntersectBf = FloatToQ16Dot16(right.x() + (y - right.y()) * leftSlope); - topRightIntersectBf = rightIntersectBf + Q16Dot16Multiply(leftSlopeFP, rowTopRight - yFP); - bottomRightIntersectAf = rightIntersectAf + Q16Dot16Multiply(rightSlopeFP, rowBottomRight - yFP); + rightIntersectBf = FloatToQ16Dot16(right.x() + (y - right.y()) * bottomRightSlope); + topRightIntersectBf = rightIntersectBf + Q16Dot16Multiply(bottomRightSlopeFP, rowTopRight - yFP); + bottomRightIntersectAf = rightIntersectAf + Q16Dot16Multiply(topRightSlopeFP, rowBottomRight - yFP); } else { topRightIntersectBf = rightIntersectBf; - bottomRightIntersectAf = rightIntersectAf + rightSlopeFP; + bottomRightIntersectAf = rightIntersectAf + topRightSlopeFP; } if (yFP == iBottomFP) { - bottomLeftIntersectBf = leftIntersectBf + Q16Dot16Multiply(rightSlopeFP, rowBottom - yFP); - bottomRightIntersectBf = rightIntersectBf + Q16Dot16Multiply(leftSlopeFP, rowBottom - yFP); + bottomLeftIntersectBf = leftIntersectBf + Q16Dot16Multiply(bottomLeftSlopeFP, rowBottom - yFP); + bottomRightIntersectBf = rightIntersectBf + Q16Dot16Multiply(bottomRightSlopeFP, rowBottom - yFP); } else { - bottomLeftIntersectBf = leftIntersectBf + rightSlopeFP; - bottomRightIntersectBf = rightIntersectBf + leftSlopeFP; + bottomLeftIntersectBf = leftIntersectBf + bottomLeftSlopeFP; + bottomRightIntersectBf = rightIntersectBf + bottomRightSlopeFP; } if (yFP < iLeftFP) { @@ -1042,21 +1060,21 @@ void QRasterizer::rasterizeLine(const QPointF &a, const QPointF &b, qreal width, if (yFP <= iLeftFP) excluded += intersectPixelFP(x, rowTop, rowBottomLeft, bottomLeftIntersectAf, topLeftIntersectAf, - leftSlopeFP, -rightSlopeFP); + topLeftSlopeFP, invTopLeftSlopeFP); if (yFP >= iLeftFP) excluded += intersectPixelFP(x, rowTopLeft, rowBottom, topLeftIntersectBf, bottomLeftIntersectBf, - rightSlopeFP, -leftSlopeFP); + bottomLeftSlopeFP, invBottomLeftSlopeFP); if (x >= rightMin) { if (yFP <= iRightFP) excluded += (rowBottomRight - rowTop) - intersectPixelFP(x, rowTop, rowBottomRight, topRightIntersectAf, bottomRightIntersectAf, - rightSlopeFP, -leftSlopeFP); + topRightSlopeFP, invTopRightSlopeFP); if (yFP >= iRightFP) excluded += (rowBottom - rowTopRight) - intersectPixelFP(x, rowTopRight, rowBottom, bottomRightIntersectBf, topRightIntersectBf, - leftSlopeFP, -rightSlopeFP); + bottomRightSlopeFP, invBottomRightSlopeFP); } Q16Dot16 coverage = rowHeight - excluded; @@ -1074,11 +1092,11 @@ void QRasterizer::rasterizeLine(const QPointF &a, const QPointF &b, qreal width, if (yFP <= iRightFP) excluded += (rowBottomRight - rowTop) - intersectPixelFP(x, rowTop, rowBottomRight, topRightIntersectAf, bottomRightIntersectAf, - rightSlopeFP, -leftSlopeFP); + topRightSlopeFP, invTopRightSlopeFP); if (yFP >= iRightFP) excluded += (rowBottom - rowTopRight) - intersectPixelFP(x, rowTopRight, rowBottom, bottomRightIntersectBf, topRightIntersectBf, - leftSlopeFP, -rightSlopeFP); + bottomRightSlopeFP, invBottomRightSlopeFP); Q16Dot16 coverage = rowHeight - excluded; buffer.addSpan(x, 1, Q16Dot16ToInt(yFP), @@ -1086,10 +1104,10 @@ void QRasterizer::rasterizeLine(const QPointF &a, const QPointF &b, qreal width, ++x; } - leftIntersectAf += leftSlopeFP; - leftIntersectBf += rightSlopeFP; - rightIntersectAf += rightSlopeFP; - rightIntersectBf += leftSlopeFP; + leftIntersectAf += topLeftSlopeFP; + leftIntersectBf += bottomLeftSlopeFP; + rightIntersectAf += topRightSlopeFP; + rightIntersectBf += bottomRightSlopeFP; topLeftIntersectAf = leftIntersectAf; topRightIntersectAf = rightIntersectAf; @@ -1103,10 +1121,10 @@ void QRasterizer::rasterizeLine(const QPointF &a, const QPointF &b, qreal width, int iBottom = bottom.y() < 0.5f? -1 : int(bottom.y() - 0.5f); int iMiddle = qMin(iLeft, iRight); - Q16Dot16 leftIntersectAf = FloatToQ16Dot16(top.x() + 0.5f + (iTop + 0.5f - top.y()) * leftSlope); - Q16Dot16 leftIntersectBf = FloatToQ16Dot16(left.x() + 0.5f + (iLeft + 1.5f - left.y()) * rightSlope); - Q16Dot16 rightIntersectAf = FloatToQ16Dot16(top.x() - 0.5f + (iTop + 0.5f - top.y()) * rightSlope); - Q16Dot16 rightIntersectBf = FloatToQ16Dot16(right.x() - 0.5f + (iRight + 1.5f - right.y()) * leftSlope); + Q16Dot16 leftIntersectAf = FloatToQ16Dot16(top.x() + 0.5f + (iTop + 0.5f - top.y()) * topLeftSlope); + Q16Dot16 leftIntersectBf = FloatToQ16Dot16(left.x() + 0.5f + (iLeft + 1.5f - left.y()) * bottomLeftSlope); + Q16Dot16 rightIntersectAf = FloatToQ16Dot16(top.x() - 0.5f + (iTop + 0.5f - top.y()) * topRightSlope); + Q16Dot16 rightIntersectBf = FloatToQ16Dot16(right.x() - 0.5f + (iRight + 1.5f - right.y()) * bottomRightSlope); int ny; int y = iTop; @@ -1128,10 +1146,10 @@ void QRasterizer::rasterizeLine(const QPointF &a, const QPointF &b, qreal width, ri += rs; \ } - DO_SEGMENT(iMiddle, leftIntersectAf, rightIntersectAf, leftSlopeFP, rightSlopeFP) - DO_SEGMENT(iRight, leftIntersectBf, rightIntersectAf, rightSlopeFP, rightSlopeFP) - DO_SEGMENT(iLeft, leftIntersectAf, rightIntersectBf, leftSlopeFP, leftSlopeFP) - DO_SEGMENT(iBottom, leftIntersectBf, rightIntersectBf, rightSlopeFP, leftSlopeFP) + DO_SEGMENT(iMiddle, leftIntersectAf, rightIntersectAf, topLeftSlopeFP, topRightSlopeFP) + DO_SEGMENT(iRight, leftIntersectBf, rightIntersectAf, bottomLeftSlopeFP, topRightSlopeFP) + DO_SEGMENT(iLeft, leftIntersectAf, rightIntersectBf, topLeftSlopeFP, bottomRightSlopeFP); + DO_SEGMENT(iBottom, leftIntersectBf, rightIntersectBf, bottomLeftSlopeFP, bottomRightSlopeFP); #undef DO_SEGMENT } } @@ -1183,12 +1201,6 @@ void QRasterizer::rasterize(const QT_FT_Outline *outline, Qt::FillRule fillRule) d->scanConverter.end(); } -static inline QT_FT_Vector PointToVector(const QPointF &p) -{ - QT_FT_Vector result = { QT_FT_Pos(p.x() * 64), QT_FT_Pos(p.y() * 64) }; - return result; -} - void QRasterizer::rasterize(const QPainterPath &path, Qt::FillRule fillRule) { if (path.isEmpty()) diff --git a/src/gui/styles/qstylehelper_p.h b/src/gui/styles/qstylehelper_p.h index 71fce55..3759929 100644 --- a/src/gui/styles/qstylehelper_p.h +++ b/src/gui/styles/qstylehelper_p.h @@ -108,7 +108,7 @@ template <typename T> { typedef HexString<T> type; enum { ExactSize = true }; - static int size(const HexString<T> &str) { return sizeof(str.val) * 2; } + static int size(const HexString<T> &) { return sizeof(T) * 2; } static inline void appendTo(const HexString<T> &str, QChar *&out) { str.write(out); } }; diff --git a/src/gui/text/qtextcontrol.cpp b/src/gui/text/qtextcontrol.cpp index 5fe0c0c..7f2c4e9 100644 --- a/src/gui/text/qtextcontrol.cpp +++ b/src/gui/text/qtextcontrol.cpp @@ -404,12 +404,6 @@ void QTextControlPrivate::init(Qt::TextFormat format, const QString &text, QText Q_Q(QTextControl); setContent(format, text, document); - QWidget *parentWidget = qobject_cast<QWidget*>(parent); - if (parentWidget) { - QTextOption opt = doc->defaultTextOption(); - opt.setTextDirection(parentWidget->layoutDirection()); - doc->setDefaultTextOption(opt); - } doc->setUndoRedoEnabled(interactionFlags & Qt::TextEditable); q->setCursorWidth(-1); } diff --git a/src/gui/widgets/qlabel.cpp b/src/gui/widgets/qlabel.cpp index bdbd0b0..42be03b 100644 --- a/src/gui/widgets/qlabel.cpp +++ b/src/gui/widgets/qlabel.cpp @@ -635,7 +635,7 @@ QSize QLabelPrivate::sizeForWidth(int w) const br = movie->currentPixmap().rect(); #endif else if (isTextLabel) { - int align = QStyle::visualAlignment(q->layoutDirection(), QFlag(this->align)); + int align = QStyle::visualAlignment(textDirection(), QFlag(this->align)); // Add indentation int m = indent; @@ -1059,7 +1059,8 @@ void QLabel::paintEvent(QPaintEvent *) drawFrame(&painter); QRect cr = contentsRect(); cr.adjust(d->margin, d->margin, -d->margin, -d->margin); - int align = QStyle::visualAlignment(layoutDirection(), QFlag(d->align)); + int align = QStyle::visualAlignment(d->isTextLabel ? d->textDirection() + : layoutDirection(), QFlag(d->align)); #ifndef QT_NO_MOVIE if (d->movie) { @@ -1119,7 +1120,8 @@ void QLabel::paintEvent(QPaintEvent *) d->control->drawContents(&painter, QRectF(), this); painter.restore(); } else { - int flags = align; + int flags = align | (d->textDirection() == Qt::LeftToRight ? Qt::TextForceLeftToRight + : Qt::TextForceRightToLeft); if (d->hasShortcut) { flags |= Qt::TextShowMnemonic; if (!style->styleHint(QStyle::SH_UnderlineShortcut, &opt, this)) @@ -1447,10 +1449,6 @@ void QLabel::changeEvent(QEvent *ev) d->control->setPalette(palette()); } else if (ev->type() == QEvent::ContentsRectChange) { d->updateLabel(); - } else if (ev->type() == QEvent::LayoutDirectionChange) { - if (d->isTextLabel && d->control) { - d->sendControlEvent(ev); - } } QFrame::changeEvent(ev); } @@ -1486,6 +1484,15 @@ void QLabel::setScaledContents(bool enable) update(contentsRect()); } +Qt::LayoutDirection QLabelPrivate::textDirection() const +{ + if (control) { + QTextOption opt = control->document()->defaultTextOption(); + return opt.textDirection(); + } + + return text.isRightToLeft() ? Qt::RightToLeft : Qt::LeftToRight; +} /*! \fn void QLabel::setAlignment(Qt::AlignmentFlag flag) @@ -1503,7 +1510,8 @@ QRect QLabelPrivate::documentRect() const Q_ASSERT_X(isTextLabel, "documentRect", "document rect called for label that is not a text label!"); QRect cr = q->contentsRect(); cr.adjust(margin, margin, -margin, -margin); - const int align = QStyle::visualAlignment(q->layoutDirection(), QFlag(this->align)); + const int align = QStyle::visualAlignment(isTextLabel ? textDirection() + : q->layoutDirection(), QFlag(this->align)); int m = indent; if (m < 0 && q->frameWidth()) // no indent, but we do have a frame m = q->fontMetrics().width(QLatin1Char('x')) / 2 - margin; @@ -1564,7 +1572,6 @@ void QLabelPrivate::ensureTextLayouted() const if (!textLayoutDirty) return; ensureTextPopulated(); - Q_Q(const QLabel); if (control) { QTextDocument *doc = control->document(); QTextOption opt = doc->defaultTextOption(); @@ -1576,8 +1583,6 @@ void QLabelPrivate::ensureTextLayouted() const else opt.setWrapMode(QTextOption::ManualWrap); - opt.setTextDirection(q->layoutDirection()); - doc->setDefaultTextOption(opt); QTextFrameFormat fmt = doc->rootFrame()->frameFormat(); diff --git a/src/gui/widgets/qlabel_p.h b/src/gui/widgets/qlabel_p.h index fba7224..83624c7 100644 --- a/src/gui/widgets/qlabel_p.h +++ b/src/gui/widgets/qlabel_p.h @@ -132,6 +132,7 @@ public: QRectF layoutRect() const; QRect documentRect() const; QPoint layoutPoint(const QPoint& p) const; + Qt::LayoutDirection textDirection() const; #ifndef QT_NO_CONTEXTMENU QMenu *createStandardContextMenu(const QPoint &pos); #endif |