// Return the layout rect - this is the rect that is given to the layout painting code // This may be different from the document rect since vertical alignment is not // done by the text layout code QRectF QLabelPrivate::layoutRect() const { QRectF cr = documentRect(); if (!control) return cr; ensureTextLayouted(); // Caculate y position manually qreal rh = control->document()->documentLayout()->documentSize().height(); qreal yo = 0; if (align & Qt::AlignVCenter) yo = qMax((cr.height()-rh)/2, qreal(0)); else if (align & Qt::AlignBottom) yo = qMax(cr.height()-rh, qreal(0)); return QRectF(cr.x(), yo + cr.y(), cr.width(), cr.height()); }
/*! Returns the size that will be used if the width of the label is \a w. If \a w is -1, the sizeHint() is returned. If \a w is 0 minimumSizeHint() is returned */ QSize QLabelPrivate::sizeForWidth(int w) const { Q_Q(const QLabel); if(q->minimumWidth() > 0) w = qMax(w, q->minimumWidth()); QSize contentsMargin(leftmargin + rightmargin, topmargin + bottommargin); QRect br; int hextra = 2 * margin; int vextra = hextra; QFontMetrics fm = q->fontMetrics(); if (pixmap && !pixmap->isNull()) { br = pixmap->rect(); br.setSize(br.size() / pixmap->devicePixelRatio()); #ifndef QT_NO_PICTURE } else if (picture && !picture->isNull()) { br = picture->boundingRect(); #endif #if QT_CONFIG(movie) } else if (movie && !movie->currentPixmap().isNull()) { br = movie->currentPixmap().rect(); br.setSize(br.size() / movie->currentPixmap().devicePixelRatio()); #endif } else if (isTextLabel) { int align = QStyle::visualAlignment(textDirection(), QFlag(this->align)); // Add indentation int m = indent; if (m < 0 && q->frameWidth()) // no indent, but we do have a frame m = fm.width(QLatin1Char('x')) - margin*2; if (m > 0) { if ((align & Qt::AlignLeft) || (align & Qt::AlignRight)) hextra += m; if ((align & Qt::AlignTop) || (align & Qt::AlignBottom)) vextra += m; } if (control) { ensureTextLayouted(); const qreal oldTextWidth = control->textWidth(); // Calculate the length of document if w is the width if (align & Qt::TextWordWrap) { if (w >= 0) { w = qMax(w-hextra-contentsMargin.width(), 0); // strip margin and indent control->setTextWidth(w); } else { control->adjustSize(); } } else { control->setTextWidth(-1); } QSizeF controlSize = control->size(); br = QRect(QPoint(0, 0), QSize(qCeil(controlSize.width()), qCeil(controlSize.height()))); // restore state control->setTextWidth(oldTextWidth); } else { // Turn off center alignment in order to avoid rounding errors for centering, // since centering involves a division by 2. At the end, all we want is the size. int flags = align & ~(Qt::AlignVCenter | Qt::AlignHCenter); if (hasShortcut) { flags |= Qt::TextShowMnemonic; QStyleOption opt; opt.initFrom(q); if (!q->style()->styleHint(QStyle::SH_UnderlineShortcut, &opt, q)) flags |= Qt::TextHideMnemonic; } bool tryWidth = (w < 0) && (align & Qt::TextWordWrap); if (tryWidth) w = qMin(fm.averageCharWidth() * 80, q->maximumSize().width()); else if (w < 0) w = 2000; w -= (hextra + contentsMargin.width()); br = fm.boundingRect(0, 0, w ,2000, flags, text); if (tryWidth && br.height() < 4*fm.lineSpacing() && br.width() > w/2) br = fm.boundingRect(0, 0, w/2, 2000, flags, text); if (tryWidth && br.height() < 2*fm.lineSpacing() && br.width() > w/4) br = fm.boundingRect(0, 0, w/4, 2000, flags, text); } } else { br = QRect(QPoint(0, 0), QSize(fm.averageCharWidth(), fm.lineSpacing())); } const QSize contentsSize(br.width() + hextra, br.height() + vextra); return (contentsSize + contentsMargin).expandedTo(q->minimumSize()); }
/*! Returns the size that will be used if the width of the label is \a w. If \a w is -1, the sizeHint() is returned. If \a w is 0 minimumSizeHint() is returned */ QSize QLabelPrivate::sizeForWidth(int w) const { Q_Q(const QLabel); QSize contentsMargin(leftmargin + rightmargin, topmargin + bottommargin); QRect br; int hextra = 2 * margin; int vextra = hextra; QFontMetrics fm = q->fontMetrics(); if (pixmap) br = pixmap->rect(); #ifndef QT_NO_PICTURE else if (picture) br = picture->boundingRect(); #endif #ifndef QT_NO_MOVIE else if (movie) br = movie->currentPixmap().rect(); #endif else if (isTextLabel) { int align = QStyle::visualAlignment(q->layoutDirection(), QFlag(this->align)); // Add indentation int m = indent; if (m < 0 && q->frameWidth()) // no indent, but we do have a frame m = fm.width(QLatin1Char('x')) - margin*2; if (m > 0) { if ((align & Qt::AlignLeft) || (align & Qt::AlignRight)) hextra += m; if ((align & Qt::AlignTop) || (align & Qt::AlignBottom)) vextra += m; } if (control) { ensureTextLayouted(); const qreal oldTextWidth = control->textWidth(); // Calculate the length of document if w is the width if (align & Qt::TextWordWrap) { if (w >= 0) { w = qMax(w-hextra-contentsMargin.width(), 0); // strip margin and indent control->setTextWidth(w); } else { control->adjustSize(); } } else { control->setTextWidth(-1); } br = QRect(QPoint(0, 0), control->size().toSize()); // restore state control->setTextWidth(oldTextWidth); } else { int flags = align; if (hasShortcut) { flags |= Qt::TextShowMnemonic; QStyleOption opt; opt.initFrom(q); if (!q->style()->styleHint(QStyle::SH_UnderlineShortcut, &opt, q)) flags |= Qt::TextHideMnemonic; } bool tryWidth = (w < 0) && (align & Qt::TextWordWrap); if (tryWidth) w = fm.averageCharWidth() * 80; else if (w < 0) w = 2000; w -= (hextra + contentsMargin.width()); br = fm.boundingRect(0, 0, w ,2000, flags, text); if (tryWidth && br.height() < 4*fm.lineSpacing() && br.width() > w/2) br = fm.boundingRect(0, 0, w/2, 2000, flags, text); if (tryWidth && br.height() < 2*fm.lineSpacing() && br.width() > w/4) br = fm.boundingRect(0, 0, w/4, 2000, flags, text); } } else { br = QRect(QPoint(0, 0), QSize(fm.averageCharWidth(), fm.lineSpacing())); } const QSize contentsSize(br.width() + hextra, br.height() + vextra); return contentsSize + contentsMargin; }