diff options
Diffstat (limited to 'src/gui')
25 files changed, 149 insertions, 455 deletions
diff --git a/src/gui/dialogs/qprintdialog_mac.mm b/src/gui/dialogs/qprintdialog_mac.mm index 84a72db..82e4db5 100644 --- a/src/gui/dialogs/qprintdialog_mac.mm +++ b/src/gui/dialogs/qprintdialog_mac.mm @@ -140,11 +140,6 @@ QT_USE_NAMESPACE QPrintDialogPrivate *d = static_cast<QPrintDialogPrivate *>(contextInfo); QPrintDialog *dialog = d->printDialog(); - // temporary hack to work around bug in deleteLater() in Qt/Mac Cocoa -#if 1 - bool deleteDialog = dialog->testAttribute(Qt::WA_DeleteOnClose); - dialog->setAttribute(Qt::WA_DeleteOnClose, false); -#endif if (returnCode == NSOKButton) { UInt32 frompage, topage; @@ -192,10 +187,6 @@ QT_USE_NAMESPACE } dialog->done((returnCode == NSOKButton) ? QDialog::Accepted : QDialog::Rejected); -#if 1 - if (deleteDialog) - delete dialog; -#endif } @end diff --git a/src/gui/graphicsview/qgraphicsitem.cpp b/src/gui/graphicsview/qgraphicsitem.cpp index 3b18c31..fc44a44 100644 --- a/src/gui/graphicsview/qgraphicsitem.cpp +++ b/src/gui/graphicsview/qgraphicsitem.cpp @@ -6655,6 +6655,11 @@ bool QGraphicsItem::sceneEvent(QEvent *event) return true; } + if (event->type() == QEvent::FocusOut) { + focusOutEvent(static_cast<QFocusEvent *>(event)); + return true; + } + if (!d_ptr->visible) { // Eaten return true; @@ -6664,9 +6669,6 @@ bool QGraphicsItem::sceneEvent(QEvent *event) case QEvent::FocusIn: focusInEvent(static_cast<QFocusEvent *>(event)); break; - case QEvent::FocusOut: - focusOutEvent(static_cast<QFocusEvent *>(event)); - break; case QEvent::GraphicsSceneContextMenu: contextMenuEvent(static_cast<QGraphicsSceneContextMenuEvent *>(event)); break; diff --git a/src/gui/graphicsview/qgraphicslayoutitem.cpp b/src/gui/graphicsview/qgraphicslayoutitem.cpp index 634f68c..ad4b2b5 100644 --- a/src/gui/graphicsview/qgraphicslayoutitem.cpp +++ b/src/gui/graphicsview/qgraphicslayoutitem.cpp @@ -48,7 +48,6 @@ #include "qgraphicslayoutitem.h" #include "qgraphicslayoutitem_p.h" #include "qwidget.h" -#include "qgraphicswidget.h" #include <QtDebug> @@ -140,11 +139,9 @@ QSizeF *QGraphicsLayoutItemPrivate::effectiveSizeHints(const QSizeF &constraint) if (!sizeHintCacheDirty && cachedConstraint == constraint) return cachedSizeHints; - const bool hasConstraint = constraint.width() >= 0 || constraint.height() >= 0; - for (int i = 0; i < Qt::NSizeHints; ++i) { cachedSizeHints[i] = constraint; - if (userSizeHints && !hasConstraint) + if (userSizeHints) combineSize(cachedSizeHints[i], userSizeHints[i]); } @@ -262,52 +259,6 @@ void QGraphicsLayoutItemPrivate::setSizeComponent( q->updateGeometry(); } - -bool QGraphicsLayoutItemPrivate::hasHeightForWidth() const -{ - Q_Q(const QGraphicsLayoutItem); - if (isLayout) { - const QGraphicsLayout *l = static_cast<const QGraphicsLayout *>(q); - for (int i = l->count() - 1; i >= 0; --i) { - if (QGraphicsLayoutItemPrivate::get(l->itemAt(i))->hasHeightForWidth()) - return true; - } - } else if (QGraphicsItem *item = q->graphicsItem()) { - if (item->isWidget()) { - QGraphicsWidget *w = static_cast<QGraphicsWidget *>(item); - if (w->layout()) { - return QGraphicsLayoutItemPrivate::get(w->layout())->hasHeightForWidth(); - } - } - } - return q->sizePolicy().hasHeightForWidth(); -} - -bool QGraphicsLayoutItemPrivate::hasWidthForHeight() const -{ - // enable this code when we add QSizePolicy::hasWidthForHeight() (For 4.8) -#if 1 - return false; -#else - Q_Q(const QGraphicsLayoutItem); - if (isLayout) { - const QGraphicsLayout *l = static_cast<const QGraphicsLayout *>(q); - for (int i = l->count() - 1; i >= 0; --i) { - if (QGraphicsLayoutItemPrivate::get(l->itemAt(i))->hasWidthForHeight()) - return true; - } - } else if (QGraphicsItem *item = q->graphicsItem()) { - if (item->isWidget()) { - QGraphicsWidget *w = static_cast<QGraphicsWidget *>(item); - if (w->layout()) { - return QGraphicsLayoutItemPrivate::get(w->layout())->hasWidthForHeight(); - } - } - } - return q->sizePolicy().hasWidthForHeight(); -#endif -} - /*! \class QGraphicsLayoutItem \brief The QGraphicsLayoutItem class can be inherited to allow your custom diff --git a/src/gui/graphicsview/qgraphicslayoutitem_p.h b/src/gui/graphicsview/qgraphicslayoutitem_p.h index b752e03..15cc7a5 100644 --- a/src/gui/graphicsview/qgraphicslayoutitem_p.h +++ b/src/gui/graphicsview/qgraphicslayoutitem_p.h @@ -65,9 +65,6 @@ class Q_AUTOTEST_EXPORT QGraphicsLayoutItemPrivate public: virtual ~QGraphicsLayoutItemPrivate(); QGraphicsLayoutItemPrivate(QGraphicsLayoutItem *parent, bool isLayout); - static QGraphicsLayoutItemPrivate *get(QGraphicsLayoutItem *q) { return q->d_func();} - static const QGraphicsLayoutItemPrivate *get(const QGraphicsLayoutItem *q) { return q->d_func();} - void init(); QSizeF *effectiveSizeHints(const QSizeF &constraint) const; QGraphicsItem *parentItem() const; @@ -76,9 +73,6 @@ public: enum SizeComponent { Width, Height }; void setSizeComponent(Qt::SizeHint which, SizeComponent component, qreal value); - bool hasHeightForWidth() const; - bool hasWidthForHeight() const; - QSizePolicy sizePolicy; QGraphicsLayoutItem *parent; diff --git a/src/gui/graphicsview/qgraphicslinearlayout.cpp b/src/gui/graphicsview/qgraphicslinearlayout.cpp index 1588364..7e8d19f 100644 --- a/src/gui/graphicsview/qgraphicslinearlayout.cpp +++ b/src/gui/graphicsview/qgraphicslinearlayout.cpp @@ -275,13 +275,17 @@ void QGraphicsLinearLayout::insertItem(int index, QGraphicsLayoutItem *item) qWarning("QGraphicsLinearLayout::insertItem: cannot insert itself"); return; } + Q_ASSERT(item); + + //the order of the following instructions is very important because + //invalidating the layout before adding the child item will make the layout happen + //before we try to paint the item + invalidate(); d->addChildLayoutItem(item); - Q_ASSERT(item); d->fixIndex(&index); d->engine.insertRow(index, d->orientation); new QGridLayoutItem(&d->engine, item, d->gridRow(index), d->gridColumn(index), 1, 1, 0, index); - invalidate(); } /*! diff --git a/src/gui/graphicsview/qgraphicsscene.cpp b/src/gui/graphicsview/qgraphicsscene.cpp index 8dc15bf..e58b93c 100644 --- a/src/gui/graphicsview/qgraphicsscene.cpp +++ b/src/gui/graphicsview/qgraphicsscene.cpp @@ -1759,7 +1759,7 @@ void QGraphicsScene::render(QPainter *painter, const QRectF &target, const QRect painter->save(); // Transform the painter. - painter->setClipRect(targetRect); + painter->setClipRect(targetRect, Qt::IntersectClip); QTransform painterTransform; painterTransform *= QTransform() .translate(targetRect.left(), targetRect.top()) diff --git a/src/gui/graphicsview/qgridlayoutengine.cpp b/src/gui/graphicsview/qgridlayoutengine.cpp index f3b2026..ae5bf90 100644 --- a/src/gui/graphicsview/qgridlayoutengine.cpp +++ b/src/gui/graphicsview/qgridlayoutengine.cpp @@ -306,20 +306,19 @@ void QGridLayoutRowData::calculateGeometries(int start, int end, qreal targetSiz ultimatePreferredSize = ultimatePreferredSize * 3 / 2; ultimateSumPreferredSizes = ultimateSumPreferredSizes * 3 / 2; - qreal ultimateFactor = (stretch * ultimateSumPreferredSizes - / sumStretches) - - (box.q_preferredSize); - qreal transitionalFactor = sumCurrentAvailable - * (ultimatePreferredSize - box.q_preferredSize) - / (ultimateSumPreferredSizes - - sumPreferredSizes); - - qreal alpha = qMin(sumCurrentAvailable, - ultimateSumPreferredSizes - sumPreferredSizes); qreal beta = ultimateSumPreferredSizes - sumPreferredSizes; + if (!beta) { + factors[i] = 1; + } else { + qreal alpha = qMin(sumCurrentAvailable, beta); + qreal ultimateFactor = (stretch * ultimateSumPreferredSizes / sumStretches) + - (box.q_preferredSize); + qreal transitionalFactor = sumCurrentAvailable * (ultimatePreferredSize - box.q_preferredSize) / beta; + + factors[i] = ((alpha * ultimateFactor) + + ((beta - alpha) * transitionalFactor)) / beta; + } - factors[i] = ((alpha * ultimateFactor) - + ((beta - alpha) * transitionalFactor)) / beta; } sumFactors += factors[i]; if (desired < sumCurrentAvailable) @@ -546,24 +545,6 @@ QSizePolicy::Policy QGridLayoutItem::sizePolicy(Qt::Orientation orientation) con : sizePolicy.verticalPolicy(); } -/* - returns true if the size policy returns true for either hasHeightForWidth() - or hasWidthForHeight() - */ -bool QGridLayoutItem::hasDynamicConstraint() const -{ - return QGraphicsLayoutItemPrivate::get(q_layoutItem)->hasHeightForWidth() - || QGraphicsLayoutItemPrivate::get(q_layoutItem)->hasWidthForHeight(); -} - -Qt::Orientation QGridLayoutItem::dynamicConstraintOrientation() const -{ - if (QGraphicsLayoutItemPrivate::get(q_layoutItem)->hasHeightForWidth()) - return Qt::Vertical; - else //if (QGraphicsLayoutItemPrivate::get(q_layoutItem)->hasWidthForHeight()) - return Qt::Horizontal; -} - QSizePolicy::ControlTypes QGridLayoutItem::controlTypes(LayoutSide /* side */) const { return q_layoutItem->sizePolicy().controlType(); @@ -632,14 +613,7 @@ QRectF QGridLayoutItem::geometryWithin(qreal x, qreal y, qreal width, qreal heig qreal cellWidth = width; qreal cellHeight = height; - QSize constraint; - if (hasDynamicConstraint()) { - if (dynamicConstraintOrientation() == Qt::Vertical) - constraint.setWidth(cellWidth); - else - constraint.setHeight(cellHeight); - } - QSizeF size = effectiveMaxSize(constraint).boundedTo(QSizeF(cellWidth, cellHeight)); + QSizeF size = effectiveMaxSize().boundedTo(QSizeF(cellWidth, cellHeight)); width = size.width(); height = size.height(); @@ -701,13 +675,13 @@ void QGridLayoutItem::insertOrRemoveRows(int row, int delta, Qt::Orientation ori Note that effectiveSizeHint does not take sizePolicy into consideration, (since it only evaluates the hints, as the name implies) */ -QSizeF QGridLayoutItem::effectiveMaxSize(const QSizeF &constraint) const +QSizeF QGridLayoutItem::effectiveMaxSize() const { - QSizeF size = constraint; + QSizeF size; bool vGrow = (sizePolicy(Qt::Vertical) & QSizePolicy::GrowFlag) == QSizePolicy::GrowFlag; bool hGrow = (sizePolicy(Qt::Horizontal) & QSizePolicy::GrowFlag) == QSizePolicy::GrowFlag; if (!vGrow || !hGrow) { - QSizeF pref = layoutItem()->effectiveSizeHint(Qt::PreferredSize, constraint); + QSizeF pref = layoutItem()->effectiveSizeHint(Qt::PreferredSize); if (!vGrow) size.setHeight(pref.height()); if (!hGrow) @@ -715,7 +689,7 @@ QSizeF QGridLayoutItem::effectiveMaxSize(const QSizeF &constraint) const } if (!size.isValid()) { - QSizeF maxSize = layoutItem()->effectiveSizeHint(Qt::MaximumSize, constraint); + QSizeF maxSize = layoutItem()->effectiveSizeHint(Qt::MaximumSize); if (size.width() == -1) size.setWidth(maxSize.width()); if (size.height() == -1) @@ -1036,7 +1010,6 @@ void QGridLayoutEngine::invalidate() q_cachedEffectiveLastRows[Ver] = -1; q_cachedDataForStyleInfo.invalidate(); q_cachedSize = QSizeF(); - q_cachedConstraintOrientation = UnknownConstraint; } static void visualRect(QRectF *geom, Qt::LayoutDirection dir, const QRectF &contentsRect) @@ -1101,13 +1074,10 @@ QRectF QGridLayoutEngine::cellRect(const QLayoutStyleInfo &styleInfo, } QSizeF QGridLayoutEngine::sizeHint(const QLayoutStyleInfo &styleInfo, Qt::SizeHint which, - const QSizeF &constraint) const + const QSizeF & /* constraint */) const { ensureColumnAndRowData(styleInfo); - if (hasDynamicConstraint()) - return dynamicallyConstrainedSizeHint(which, constraint); - switch (which) { case Qt::MinimumSize: return QSizeF(q_totalBoxes[Hor].q_minimumSize, q_totalBoxes[Ver].q_minimumSize); @@ -1405,11 +1375,7 @@ void QGridLayoutEngine::fillRowData(QGridLayoutRowData *rowData, const QLayoutSt box = &multiCell.q_box; multiCell.q_stretch = itemStretch; } - // Items with constraints are not included in the orientation that - // they are constrained (since it depends on the hfw/constraint function). - // They must be combined at a later stage. - if (!item->hasDynamicConstraint() || orientation != item->dynamicConstraintOrientation()) - box->combine(item->box(orientation)); + box->combine(item->box(orientation)); if (effectiveRowSpan == 1) { QSizePolicy::ControlTypes controls = item->controlTypes(top); @@ -1566,138 +1532,6 @@ void QGridLayoutEngine::ensureColumnAndRowData(const QLayoutStyleInfo &styleInfo q_cachedDataForStyleInfo = styleInfo; } -QSizeF QGridLayoutEngine::dynamicallyConstrainedSizeHint(Qt::SizeHint which, - const QSizeF &constraint) const -{ - Q_ASSERT(hasDynamicConstraint()); - if (constraint.width() < 0 && constraint.height() < 0) { - // Process the hfw / wfh items that we did not process in fillRowData() - const Qt::Orientation constraintOrient = constraintOrientation(); - - QGridLayoutRowData rowData = constraintOrient == Qt::Vertical ? q_rowData : q_columnData; - for (int i = q_items.count() - 1; i >= 0; --i) { - QGridLayoutItem *item = q_items.at(i); - if (item->hasDynamicConstraint()) { - QGridLayoutBox box = item->box(constraintOrient); - QGridLayoutBox &rowBox = rowData.boxes[item->firstRow(constraintOrient)]; - rowBox.combine(box); - } - } - - QGridLayoutBox totalBoxes[2]; - if (constraintOrient == Qt::Vertical) { - totalBoxes[Hor] = q_columnData.totalBox(0, columnCount()); - totalBoxes[Ver] = rowData.totalBox(0, rowCount()); - } else { - totalBoxes[Hor] = rowData.totalBox(0, columnCount()); - totalBoxes[Ver] = q_rowData.totalBox(0, rowCount()); - } - return QSizeF(totalBoxes[Hor].q_sizes(which), totalBoxes[Ver].q_sizes(which)); - } - - - Q_ASSERT(constraint.width() >= 0 || constraint.height() >= 0); - q_xx.resize(columnCount()); - q_yy.resize(rowCount()); - q_widths.resize(columnCount()); - q_heights.resize(rowCount()); - q_descents.resize(rowCount()); - - - const Qt::Orientation orientation = constraintOrientation(); - QGridLayoutRowData *colData; - QGridLayoutRowData constrainedRowData; - QGridLayoutBox *totalBox; - qreal *sizes; - qreal *pos; - qreal *descents; - qreal targetSize; - qreal cCount; - qreal rCount; - - if (orientation == Qt::Vertical) { - // height for width - colData = &q_columnData; - totalBox = &q_totalBoxes[Hor]; - sizes = q_widths.data(); - pos = q_xx.data(); - descents = 0; - targetSize = constraint.width(); - cCount = columnCount(); - rCount = rowCount(); - constrainedRowData = q_rowData; - } else { - // width for height - colData = &q_rowData; - totalBox = &q_totalBoxes[Ver]; - sizes = q_heights.data(); - pos = q_yy.data(); - descents = q_descents.data(); - targetSize = constraint.height(); - cCount = rowCount(); - rCount = columnCount(); - constrainedRowData = q_columnData; - } - colData->calculateGeometries(0, cCount, targetSize, pos, sizes, descents, *totalBox); - for (int i = q_items.count() - 1; i >= 0; --i) { - QGridLayoutItem *item = q_items.at(i); - - if (item->hasDynamicConstraint()) { - const qreal size = sizes[item->firstColumn(orientation)]; - QGridLayoutBox box = item->box(orientation, size); - QGridLayoutBox &rowBox = constrainedRowData.boxes[item->firstRow(orientation)]; - rowBox.combine(box); - } - } - const qreal newSize = constrainedRowData.totalBox(0, rCount).q_sizes(which); - - return (orientation == Qt::Vertical) ? QSizeF(targetSize, newSize) : QSizeF(newSize, targetSize); -} - - -/** - returns false if the layout has contradicting constraints (i.e. some items with a horizontal - constraint and other items with a vertical constraint) - */ -bool QGridLayoutEngine::ensureDynamicConstraint() const -{ - if (q_cachedConstraintOrientation == UnknownConstraint) { - for (int i = q_items.count() - 1; i >= 0; --i) { - QGridLayoutItem *item = q_items.at(i); - if (item->hasDynamicConstraint()) { - Qt::Orientation itemConstraintOrientation = item->dynamicConstraintOrientation(); - if (q_cachedConstraintOrientation == UnknownConstraint) { - q_cachedConstraintOrientation = itemConstraintOrientation; - } else if (q_cachedConstraintOrientation != itemConstraintOrientation) { - q_cachedConstraintOrientation = UnfeasibleConstraint; - qWarning("QGridLayoutEngine: Unfeasible, cannot mix horizontal and" - " vertical constraint in the same layout"); - return false; - } - } - } - if (q_cachedConstraintOrientation == UnknownConstraint) - q_cachedConstraintOrientation = NoConstraint; - } - return true; -} - -bool QGridLayoutEngine::hasDynamicConstraint() const -{ - if (!ensureDynamicConstraint()) - return false; - return q_cachedConstraintOrientation != NoConstraint; -} - -/* - * return value is only valid if hasConstraint() returns true - */ -Qt::Orientation QGridLayoutEngine::constraintOrientation() const -{ - (void)ensureDynamicConstraint(); - return (Qt::Orientation)q_cachedConstraintOrientation; -} - void QGridLayoutEngine::ensureGeometries(const QLayoutStyleInfo &styleInfo, const QSizeF &size) const { @@ -1710,74 +1544,10 @@ void QGridLayoutEngine::ensureGeometries(const QLayoutStyleInfo &styleInfo, q_widths.resize(columnCount()); q_heights.resize(rowCount()); q_descents.resize(rowCount()); - - - Qt::Orientation orientation = Qt::Vertical; - if (hasDynamicConstraint()) - orientation = constraintOrientation(); - - /* - In order to do hfw we need to first distribute the columns, then the rows. - In order to do wfh we need to first distribute the rows, then the columns. - - If there is no constraint, the order of distributing the rows or columns first is irrelevant. - We choose horizontal just to keep the same behaviour as before (however, there shouldn't - be any behaviour difference). - */ - - QGridLayoutRowData *colData; - QGridLayoutRowData rowData; - qreal *widths; - qreal *heights; - qreal *xx; - qreal *yy; - qreal *xdescents = 0; - qreal *ydescents = 0; - qreal cCount; - qreal rCount; - QSizeF oSize = size; - if (orientation == Qt::Vertical) { - // height for width - colData = &q_columnData; - rowData = q_rowData; - widths = q_widths.data(); - heights = q_heights.data(); - xx = q_xx.data(); - yy = q_yy.data(); - cCount = columnCount(); - rCount = rowCount(); - ydescents = q_descents.data(); - } else { - // width for height - colData = &q_rowData; - rowData = q_columnData; - widths = q_heights.data(); - heights = q_widths.data(); - xx = q_yy.data(); - yy = q_xx.data(); - cCount = rowCount(); - rCount = columnCount(); - xdescents = q_descents.data(); - oSize.transpose(); - } - - colData->calculateGeometries(0, cCount, oSize.width(), xx, widths, - xdescents, q_totalBoxes[orientation == Qt::Horizontal]); - for (int i = q_items.count() - 1; i >= 0; --i) { - QGridLayoutItem *item = q_items.at(i); - const int col = item->firstColumn(orientation); - const int row = item->firstRow(orientation); - if (item->hasDynamicConstraint()) { - const qreal sz = widths[col]; - QGridLayoutBox box = item->box(orientation, sz); - rowData.boxes[row].combine(box); - } - } - - QGridLayoutBox &totalBox = q_totalBoxes[orientation == Qt::Vertical]; - totalBox = rowData.totalBox(0, rCount); - rowData.calculateGeometries(0, rCount, oSize.height(), yy, heights, - ydescents, totalBox); + q_columnData.calculateGeometries(0, columnCount(), size.width(), q_xx.data(), q_widths.data(), + 0, q_totalBoxes[Hor]); + q_rowData.calculateGeometries(0, rowCount(), size.height(), q_yy.data(), q_heights.data(), + q_descents.data(), q_totalBoxes[Ver]); q_cachedSize = size; } diff --git a/src/gui/graphicsview/qgridlayoutengine_p.h b/src/gui/graphicsview/qgridlayoutengine_p.h index 580af7e..9ac9a8e 100644 --- a/src/gui/graphicsview/qgridlayoutengine_p.h +++ b/src/gui/graphicsview/qgridlayoutengine_p.h @@ -91,14 +91,6 @@ enum LayoutSide { Bottom }; -enum { - NoConstraint, - HorizontalConstraint, - VerticalConstraint, - UnknownConstraint, // need to update cache - UnfeasibleConstraint // not feasible, it be has some items with Vertical and others with Horizontal constraints -}; - template <typename T> class QLayoutParameter { @@ -278,10 +270,6 @@ public: inline void setAlignment(Qt::Alignment alignment) { q_alignment = alignment; } QSizePolicy::Policy sizePolicy(Qt::Orientation orientation) const; - - bool hasDynamicConstraint() const; - Qt::Orientation dynamicConstraintOrientation() const; - QSizePolicy::ControlTypes controlTypes(LayoutSide side) const; QSizeF sizeHint(Qt::SizeHint which, const QSizeF &constraint = QSizeF()) const; QGridLayoutBox box(Qt::Orientation orientation, qreal constraint = -1.0) const; @@ -292,7 +280,7 @@ public: void setGeometry(const QRectF &rect); void transpose(); void insertOrRemoveRows(int row, int delta, Qt::Orientation orientation = Qt::Vertical); - QSizeF effectiveMaxSize(const QSizeF &constraint) const; + QSizeF effectiveMaxSize() const; #ifdef QT_DEBUG void dump(int indent = 0) const; @@ -384,14 +372,6 @@ public: int column, int rowSpan, int columnSpan) const; QSizeF sizeHint(const QLayoutStyleInfo &styleInfo, Qt::SizeHint which, const QSizeF &constraint) const; - - // heightForWidth / widthForHeight support - QSizeF dynamicallyConstrainedSizeHint(Qt::SizeHint which, const QSizeF &constraint) const; - bool ensureDynamicConstraint() const; - bool hasDynamicConstraint() const; - Qt::Orientation constraintOrientation() const; - - QSizePolicy::ControlTypes controlTypes(LayoutSide side) const; void transpose(); void setVisualDirection(Qt::LayoutDirection direction); @@ -425,7 +405,6 @@ private: // Lazily computed from the above user input mutable int q_cachedEffectiveFirstRows[NOrientations]; mutable int q_cachedEffectiveLastRows[NOrientations]; - mutable quint8 q_cachedConstraintOrientation : 2; // Layout item input mutable QLayoutStyleInfo q_cachedDataForStyleInfo; diff --git a/src/gui/image/qgifhandler.cpp b/src/gui/image/qgifhandler.cpp index 124d27b..a050baf 100644 --- a/src/gui/image/qgifhandler.cpp +++ b/src/gui/image/qgifhandler.cpp @@ -505,17 +505,26 @@ int QGIFFormat::decode(QImage *image, const uchar *buffer, int length, code=oldcode; } while (code>=clear_code+2) { + if (code >= max_code) { + state = Error; + return -1; + } *sp++=table[1][code]; if (code==table[0][code]) { state=Error; - break; + return -1; } if (sp-stack>=(1<<(max_lzw_bits))*2) { state=Error; - break; + return -1; } code=table[0][code]; } + if (code < 0) { + state = Error; + return -1; + } + *sp++=firstcode=table[1][code]; code=max_code; if (code<(1<<max_lzw_bits)) { diff --git a/src/gui/image/qjpeghandler.cpp b/src/gui/image/qjpeghandler.cpp index b9eda05..d47cc82 100644 --- a/src/gui/image/qjpeghandler.cpp +++ b/src/gui/image/qjpeghandler.cpp @@ -648,22 +648,28 @@ static bool write_jpeg_image(const QImage &image, QIODevice *device, int sourceQ break; case QImage::Format_RGB32: case QImage::Format_ARGB32: - case QImage::Format_ARGB32_Premultiplied: { - const QRgb* rgb = (const QRgb*)image.constScanLine(cinfo.next_scanline); - for (int i=0; i<w; i++) { - *row++ = qRed(*rgb); - *row++ = qGreen(*rgb); - *row++ = qBlue(*rgb); - ++rgb; + case QImage::Format_ARGB32_Premultiplied: + { + const QRgb* rgb = (const QRgb*)image.constScanLine(cinfo.next_scanline); + for (int i=0; i<w; i++) { + *row++ = qRed(*rgb); + *row++ = qGreen(*rgb); + *row++ = qBlue(*rgb); + ++rgb; + } } break; - } default: - for (int i=0; i<w; i++) { - QRgb pix = image.pixel(i, cinfo.next_scanline); - *row++ = qRed(pix); - *row++ = qGreen(pix); - *row++ = qBlue(pix); + { + // (Testing shows that this way is actually faster than converting to RGB888 + memcpy) + QImage rowImg = image.copy(0, cinfo.next_scanline, w, 1).convertToFormat(QImage::Format_RGB32); + const QRgb* rgb = (const QRgb*)rowImg.constScanLine(0); + for (int i=0; i<w; i++) { + *row++ = qRed(*rgb); + *row++ = qGreen(*rgb); + *row++ = qBlue(*rgb); + ++rgb; + } } break; } diff --git a/src/gui/image/qpnghandler.cpp b/src/gui/image/qpnghandler.cpp index dc54313..935aba0 100644 --- a/src/gui/image/qpnghandler.cpp +++ b/src/gui/image/qpnghandler.cpp @@ -678,41 +678,19 @@ bool QPNGImageWriter::writeImage(const QImage& image, int off_x, int off_y) return writeImage(image, -1, QString(), off_x, off_y); } -bool Q_INTERNAL_WIN_NO_THROW QPNGImageWriter::writeImage(const QImage& image_in, int quality_in, const QString &description, +bool Q_INTERNAL_WIN_NO_THROW QPNGImageWriter::writeImage(const QImage& image, int quality_in, const QString &description, int off_x_in, int off_y_in) { #ifdef QT_NO_IMAGE_TEXT Q_UNUSED(description); #endif - QImage image; - switch (image_in.format()) { - case QImage::Format_ARGB32_Premultiplied: - case QImage::Format_ARGB4444_Premultiplied: - case QImage::Format_ARGB8555_Premultiplied: - case QImage::Format_ARGB8565_Premultiplied: - case QImage::Format_ARGB6666_Premultiplied: - image = image_in.convertToFormat(QImage::Format_ARGB32); - break; - case QImage::Format_RGB16: - case QImage::Format_RGB444: - case QImage::Format_RGB555: - case QImage::Format_RGB666: - case QImage::Format_RGB888: - image = image_in.convertToFormat(QImage::Format_RGB32); - break; - default: - image = image_in; - break; - } - QPoint offset = image.offset(); int off_x = off_x_in + offset.x(); int off_y = off_y_in + offset.y(); png_structp png_ptr; png_infop info_ptr; - png_bytep* row_pointers; png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING,0,0,0); if (!png_ptr) { @@ -743,13 +721,18 @@ bool Q_INTERNAL_WIN_NO_THROW QPNGImageWriter::writeImage(const QImage& image_in, png_set_write_fn(png_ptr, (void*)this, qpiw_write_fn, qpiw_flush_fn); + + int color_type = 0; + if (image.colorCount()) + color_type = PNG_COLOR_TYPE_PALETTE; + else if (image.hasAlphaChannel()) + color_type = PNG_COLOR_TYPE_RGB_ALPHA; + else + color_type = PNG_COLOR_TYPE_RGB; + png_set_IHDR(png_ptr, info_ptr, image.width(), image.height(), - image.depth() == 1 ? 1 : 8 /* per channel */, - image.depth() == 32 - ? image.format() == QImage::Format_RGB32 - ? PNG_COLOR_TYPE_RGB - : PNG_COLOR_TYPE_RGB_ALPHA - : PNG_COLOR_TYPE_PALETTE, 0, 0, 0); // also sets #channels + image.depth() == 1 ? 1 : 8, // per channel + color_type, 0, 0, 0); // sets #channels if (gamma != 0.0) { png_set_gAMA(png_ptr, info_ptr, 1.0/gamma); @@ -794,8 +777,9 @@ bool Q_INTERNAL_WIN_NO_THROW QPNGImageWriter::writeImage(const QImage& image_in, png_set_swap_alpha(png_ptr); } - // Qt==ARGB==Big(ARGB)==Little(BGRA) - if (QSysInfo::ByteOrder == QSysInfo::LittleEndian) { + // Qt==ARGB==Big(ARGB)==Little(BGRA). But RGB888 is RGB regardless + if (QSysInfo::ByteOrder == QSysInfo::LittleEndian + && image.format() != QImage::Format_RGB888) { png_set_bgr(png_ptr); } @@ -820,7 +804,7 @@ bool Q_INTERNAL_WIN_NO_THROW QPNGImageWriter::writeImage(const QImage& image_in, if (image.depth() != 1) png_set_packing(png_ptr); - if (image.format() == QImage::Format_RGB32) + if (color_type == PNG_COLOR_TYPE_RGB && image.format() != QImage::Format_RGB888) png_set_filler(png_ptr, 0, QSysInfo::ByteOrder == QSysInfo::BigEndian ? PNG_FILLER_BEFORE : PNG_FILLER_AFTER); @@ -841,22 +825,36 @@ bool Q_INTERNAL_WIN_NO_THROW QPNGImageWriter::writeImage(const QImage& image_in, png_write_chunk(png_ptr, (png_byte*)"gIFg", data, 4); } - png_uint_32 width; - png_uint_32 height; - int bit_depth; - int color_type; - png_get_IHDR(png_ptr, info_ptr, &width, &height, &bit_depth, &color_type, - 0, 0, 0); - - const uchar *data = (static_cast<const QImage *>(&image))->bits(); - int bpl = image.bytesPerLine(); - row_pointers = new png_bytep[height]; - uint y; - for (y=0; y<height; y++) { - row_pointers[y] = (png_bytep)(data + y * bpl); + int height = image.height(); + int width = image.width(); + switch (image.format()) { + case QImage::Format_Mono: + case QImage::Format_MonoLSB: + case QImage::Format_Indexed8: + case QImage::Format_RGB32: + case QImage::Format_ARGB32: + case QImage::Format_RGB888: + { + png_bytep* row_pointers = new png_bytep[height]; + for (int y=0; y<height; y++) + row_pointers[y] = (png_bytep)image.constScanLine(y); + png_write_image(png_ptr, row_pointers); + delete [] row_pointers; + } + break; + default: + { + QImage::Format fmt = image.hasAlphaChannel() ? QImage::Format_ARGB32 : QImage::Format_RGB32; + QImage row; + png_bytep row_pointers[1]; + for (int y=0; y<height; y++) { + row = image.copy(0, y, width, 1).convertToFormat(fmt); + row_pointers[0] = png_bytep(row.constScanLine(0)); + png_write_rows(png_ptr, row_pointers, 1); + } + } + break; } - png_write_image(png_ptr, row_pointers); - delete [] row_pointers; png_write_end(png_ptr, info_ptr); frames_written++; diff --git a/src/gui/painting/qgrayraster.c b/src/gui/painting/qgrayraster.c index d0e25a9..ec9ebeb 100644 --- a/src/gui/painting/qgrayraster.c +++ b/src/gui/painting/qgrayraster.c @@ -325,6 +325,7 @@ { void* buffer; long buffer_size; + long buffer_allocated_size; int band_size; void* memory; PWorker worker; @@ -1791,7 +1792,7 @@ // If raster object and raster buffer are allocated, but // raster size isn't of the minimum size, indicate out of // memory. - if (raster && raster->buffer && raster->buffer_size < MINIMUM_POOL_SIZE ) + if (raster->buffer_allocated_size < MINIMUM_POOL_SIZE ) return ErrRaster_OutOfMemory; /* return immediately if the outline is empty */ @@ -1930,6 +1931,7 @@ rast->buffer_size = 0; rast->worker = NULL; } + rast->buffer_allocated_size = pool_size; } } diff --git a/src/gui/painting/qpaintengine_raster.cpp b/src/gui/painting/qpaintengine_raster.cpp index 36e1082..9749244 100644 --- a/src/gui/painting/qpaintengine_raster.cpp +++ b/src/gui/painting/qpaintengine_raster.cpp @@ -4233,6 +4233,8 @@ void QRasterPaintEnginePrivate::rasterize(QT_FT_Outline *outline, break; } + rendered_spans += q_gray_rendered_spans(*grayRaster.data()); + #if defined(Q_WS_WIN64) _aligned_free(rasterPoolBase); #else @@ -4251,8 +4253,6 @@ void QRasterPaintEnginePrivate::rasterize(QT_FT_Outline *outline, #endif Q_CHECK_PTR(rasterPoolBase); // note: we just freed the old rasterPoolBase. I hope it's not fatal. - rendered_spans += q_gray_rendered_spans(*grayRaster.data()); - qt_ft_grays_raster.raster_done(*grayRaster.data()); qt_ft_grays_raster.raster_new(grayRaster.data()); qt_ft_grays_raster.raster_reset(*grayRaster.data(), rasterPoolBase, rasterPoolSize); diff --git a/src/gui/painting/qpaintengineex.cpp b/src/gui/painting/qpaintengineex.cpp index 1e857e4..c1e3d66 100644 --- a/src/gui/painting/qpaintengineex.cpp +++ b/src/gui/painting/qpaintengineex.cpp @@ -517,7 +517,7 @@ void QPaintEngineEx::stroke(const QVectorPath &path, const QPen &pen) QPainterPath painterPath = state()->matrix.map(path.convertToPainterPath()); d->activeStroker->strokePath(painterPath, d->strokeHandler, QTransform()); } else { - d->activeStroker->setCurveThresholdFromTransform(state()->matrix); + d->activeStroker->setCurveThresholdFromTransform(QTransform()); d->activeStroker->begin(d->strokeHandler); if (types) { while (points < lastPoint) { diff --git a/src/gui/painting/qpainter.cpp b/src/gui/painting/qpainter.cpp index 5fbe3ed..7fed7e4 100644 --- a/src/gui/painting/qpainter.cpp +++ b/src/gui/painting/qpainter.cpp @@ -6185,7 +6185,7 @@ void QPainter::drawText(const QRectF &r, int flags, const QString &str, QRectF * By default, QPainter draws text anti-aliased. - \note The y-position is used as the baseline of the font. + \note The y-position is used as the top of the font. \sa Qt::AlignmentFlag, Qt::TextFlag */ diff --git a/src/gui/painting/qpdf.cpp b/src/gui/painting/qpdf.cpp index 6e02435..ba5d164 100644 --- a/src/gui/painting/qpdf.cpp +++ b/src/gui/painting/qpdf.cpp @@ -916,24 +916,6 @@ const char *QPdf::paperSizeToString(QPrinter::PaperSize paperSize) } -QByteArray QPdf::stripSpecialCharacters(const QByteArray &string) -{ - QByteArray s = string; - s.replace(' ', ""); - s.replace('(', ""); - s.replace(')', ""); - s.replace('<', ""); - s.replace('>', ""); - s.replace('[', ""); - s.replace(']', ""); - s.replace('{', ""); - s.replace('}', ""); - s.replace('/', ""); - s.replace('%', ""); - return s; -} - - // -------------------------- base engine, shared code between PS and PDF ----------------------- QPdfBaseEngine::QPdfBaseEngine(QPdfBaseEnginePrivate &dd, PaintEngineFeatures f) diff --git a/src/gui/painting/qpdf_p.h b/src/gui/painting/qpdf_p.h index 9c4d05d..5c5ceb4 100644 --- a/src/gui/painting/qpdf_p.h +++ b/src/gui/painting/qpdf_p.h @@ -156,8 +156,6 @@ namespace QPdf { PaperSize paperSize(QPrinter::PaperSize paperSize); const char *paperSizeToString(QPrinter::PaperSize paperSize); - - QByteArray stripSpecialCharacters(const QByteArray &string); } diff --git a/src/gui/painting/qrasterdefs_p.h b/src/gui/painting/qrasterdefs_p.h index 4131e4b..f6339ed 100644 --- a/src/gui/painting/qrasterdefs_p.h +++ b/src/gui/painting/qrasterdefs_p.h @@ -100,7 +100,7 @@ QT_FT_BEGIN_HEADER /* distances in integer font units, or 16,16, or 26.6 fixed float */ /* pixel coordinates. */ /* */ - typedef signed long QT_FT_Pos; + typedef signed int QT_FT_Pos; /*************************************************************************/ diff --git a/src/gui/painting/qstroker.cpp b/src/gui/painting/qstroker.cpp index 9cff339..9decf41 100644 --- a/src/gui/painting/qstroker.cpp +++ b/src/gui/painting/qstroker.cpp @@ -190,6 +190,7 @@ static inline qreal adapted_angle_on_x(const QLineF &line) QStrokerOps::QStrokerOps() : m_elements(0) , m_curveThreshold(qt_real_to_fixed(0.25)) + , m_dashThreshold(qt_real_to_fixed(0.25)) , m_customData(0) , m_moveTo(0) , m_lineTo(0) @@ -243,7 +244,7 @@ void QStrokerOps::strokePath(const QPainterPath &path, void *customData, const Q if (path.isEmpty()) return; - setCurveThresholdFromTransform(matrix); + setCurveThresholdFromTransform(QTransform()); begin(customData); int count = path.elementCount(); if (matrix.isIdentity()) { @@ -315,7 +316,7 @@ void QStrokerOps::strokePolygon(const QPointF *points, int pointCount, bool impl if (!pointCount) return; - setCurveThresholdFromTransform(matrix); + setCurveThresholdFromTransform(QTransform()); begin(data); if (matrix.isIdentity()) { moveTo(qt_real_to_fixed(points[0].x()), qt_real_to_fixed(points[0].y())); @@ -356,7 +357,7 @@ void QStrokerOps::strokeEllipse(const QRectF &rect, void *data, const QTransform } } - setCurveThresholdFromTransform(matrix); + setCurveThresholdFromTransform(QTransform()); begin(data); moveTo(qt_real_to_fixed(start.x()), qt_real_to_fixed(start.y())); for (int i=0; i<12; i+=3) { @@ -1142,7 +1143,7 @@ void QDashStroker::processCurrentSubpath() QPainterPath dashPath; - QSubpathFlatIterator it(&m_elements, m_curveThreshold); + QSubpathFlatIterator it(&m_elements, m_dashThreshold); qfixed2d prev = it.next(); bool clipping = !m_clip_rect.isEmpty(); diff --git a/src/gui/painting/qstroker_p.h b/src/gui/painting/qstroker_p.h index d646135..5607a8e 100644 --- a/src/gui/painting/qstroker_p.h +++ b/src/gui/painting/qstroker_p.h @@ -168,7 +168,7 @@ public: { qreal scale; qt_scaleForTransform(transform, &scale); - setCurveThreshold(scale == 0 ? qreal(0.5) : (qreal(0.5) / scale)); + m_dashThreshold = scale == 0 ? qreal(0.5) : (qreal(0.5) / scale); } void setCurveThreshold(qfixed threshold) { m_curveThreshold = threshold; } @@ -184,6 +184,7 @@ protected: QRectF m_clip_rect; qfixed m_curveThreshold; + qfixed m_dashThreshold; void *m_customData; qStrokerMoveToHook m_moveTo; diff --git a/src/gui/text/qfontengine.cpp b/src/gui/text/qfontengine.cpp index 0dfd295..7e04180 100644 --- a/src/gui/text/qfontengine.cpp +++ b/src/gui/text/qfontengine.cpp @@ -46,7 +46,6 @@ #include "qpainter.h" #include "qpainterpath.h" #include "qvarlengtharray.h" -#include <private/qpdf_p.h> #include <qmath.h> #include <qendian.h> #include <private/qharfbuzz_p.h> @@ -667,11 +666,7 @@ void QFontEngine::removeGlyphFromCache(glyph_t) QFontEngine::Properties QFontEngine::properties() const { Properties p; -#ifndef QT_NO_PRINTER - QByteArray psname = QPdf::stripSpecialCharacters(fontDef.family.toUtf8()); -#else - QByteArray psname = fontDef.family.toUtf8(); -#endif + QByteArray psname = QFontEngine::convertToPostscriptFontFamilyName(fontDef.family.toUtf8()); psname += '-'; psname += QByteArray::number(fontDef.style); psname += '-'; @@ -1081,6 +1076,23 @@ quint32 QFontEngine::getTrueTypeGlyphIndex(const uchar *cmap, uint unicode) return 0; } +QByteArray QFontEngine::convertToPostscriptFontFamilyName(const QByteArray &family) +{ + QByteArray f = family; + f.replace(' ', ""); + f.replace('(', ""); + f.replace(')', ""); + f.replace('<', ""); + f.replace('>', ""); + f.replace('[', ""); + f.replace(']', ""); + f.replace('{', ""); + f.replace('}', ""); + f.replace('/', ""); + f.replace('%', ""); + return f; +} + Q_GLOBAL_STATIC_WITH_INITIALIZER(QVector<QRgb>, qt_grayPalette, { x->resize(256); QRgb *it = x->data(); diff --git a/src/gui/text/qfontengine_ft.cpp b/src/gui/text/qfontengine_ft.cpp index a9b25f5..cc6af7f 100644 --- a/src/gui/text/qfontengine_ft.cpp +++ b/src/gui/text/qfontengine_ft.cpp @@ -51,7 +51,6 @@ #include "qabstractfileengine.h" #include "qthreadstorage.h" #include <qmath.h> -#include <private/qpdf_p.h> #include <private/qharfbuzz_p.h> #include "qfontengine_ft_p.h" @@ -1196,10 +1195,7 @@ QFontEngine::Properties QFontEngineFT::properties() const { Properties p = freetype->properties(); if (p.postscriptName.isEmpty()) { - p.postscriptName = fontDef.family.toUtf8(); -#ifndef QT_NO_PRINTER - p.postscriptName = QPdf::stripSpecialCharacters(p.postscriptName); -#endif + p.postscriptName = QFontEngine::convertToPostscriptFontFamilyName(fontDef.family.toUtf8()); } return freetype->properties(); diff --git a/src/gui/text/qfontengine_mac.mm b/src/gui/text/qfontengine_mac.mm index bdf3848..b3efe6c 100644 --- a/src/gui/text/qfontengine_mac.mm +++ b/src/gui/text/qfontengine_mac.mm @@ -46,7 +46,6 @@ #include <qbitmap.h> #include <private/qpaintengine_mac_p.h> #include <private/qprintengine_mac_p.h> -#include <private/qpdf_p.h> #include <qglobal.h> #include <qpixmap.h> #include <qpixmapcache.h> @@ -1853,7 +1852,7 @@ QFontEngine::Properties QFontEngineMac::properties() const QCFString psName; if (ATSFontGetPostScriptName(FMGetATSFontRefFromFont(fontID), kATSOptionFlagsDefault, &psName) == noErr) props.postscriptName = QString(psName).toUtf8(); - props.postscriptName = QPdf::stripSpecialCharacters(props.postscriptName); + props.postscriptName = QFontEngine::convertToPostscriptFontFamilyName(props.postscriptName); return props; } diff --git a/src/gui/text/qfontengine_p.h b/src/gui/text/qfontengine_p.h index 3b91cd8..571cf98 100644 --- a/src/gui/text/qfontengine_p.h +++ b/src/gui/text/qfontengine_p.h @@ -227,6 +227,8 @@ public: static const uchar *getCMap(const uchar *table, uint tableSize, bool *isSymbolFont, int *cmapSize); static quint32 getTrueTypeGlyphIndex(const uchar *cmap, uint unicode); + static QByteArray convertToPostscriptFontFamilyName(const QByteArray &fontFamily); + QAtomicInt ref; QFontDef fontDef; uint cache_cost; // amount of mem used in kb by the font diff --git a/src/gui/text/qfontengine_win.cpp b/src/gui/text/qfontengine_win.cpp index ef1b504..7609ee5 100644 --- a/src/gui/text/qfontengine_win.cpp +++ b/src/gui/text/qfontengine_win.cpp @@ -63,7 +63,6 @@ #include <qbitmap.h> #include <private/qpainter_p.h> -#include <private/qpdf_p.h> #include "qpaintengine.h" #include "qvarlengtharray.h" #include <private/qpaintengine_raster_p.h> @@ -1039,9 +1038,7 @@ QFontEngine::Properties QFontEngineWin::properties() const p.italicAngle = otm->otmItalicAngle; p.postscriptName = QString::fromWCharArray((wchar_t *)((char *)otm + (quintptr)otm->otmpFamilyName)).toLatin1(); p.postscriptName += QString::fromWCharArray((wchar_t *)((char *)otm + (quintptr)otm->otmpStyleName)).toLatin1(); -#ifndef QT_NO_PRINTER - p.postscriptName = QPdf::stripSpecialCharacters(p.postscriptName); -#endif + p.postscriptName = QFontEngine::convertToPostscriptFontFamilyName(p.postscriptName); p.boundingBox = QRectF(otm->otmrcFontBox.left, -otm->otmrcFontBox.top, otm->otmrcFontBox.right - otm->otmrcFontBox.left, otm->otmrcFontBox.top - otm->otmrcFontBox.bottom); |