void TextLabel::layoutText(QTextLayout &layout, const QString &text, const QSize &constraints)
{
    QFontMetrics metrics(layout.font());
    int leading = metrics.leading();
    int height = 0;
    int maxWidth = constraints.width();
    int widthUsed = 0;
    int lineSpacing = metrics.lineSpacing();
    QTextLine line;

    layout.setText(text);

    layout.beginLayout();
    while ((line = layout.createLine()).isValid()) {
        height += leading;

        // Make the last line that will fit infinitely long.
        // drawTextLayout() will handle this by fading the line out
        // if it won't fit in the constraints.
        if (height + 2 * lineSpacing > constraints.height()) {
            line.setPosition(QPoint(0, height));
            break;
        }

        line.setLineWidth(maxWidth);
        line.setPosition(QPoint(0, height));

        height += int(line.height());
        widthUsed = int(qMax(qreal(widthUsed), line.naturalTextWidth()));
    }
    layout.endLayout();
}
Exemple #2
0
  void UserIcon::init(){
    QString text = tr(user_->name().c_str());
    layout_ = new QTextLayout(text,
                              d_->users_scene()->font());
    QFontMetricsF fm(d_->users_scene()->font());
    layout_->beginLayout();
    QTextLine line = layout_->createLine();
    //line.setNumColumns(1);
    QSizeF text_size_ = fm.boundingRect(text).size();
    // TODO: Figure out what these numbers are all about, why width/4, height/4
    //line.setPosition(QPointF(s.width()/4.0,
                            // -s.height()/4.0));
    line.setPosition(QPointF());

    layout_->endLayout();
    layout_->setCacheEnabled(true);

    menu_ = new QMenu(tr(user_->name().c_str()));
    show_on_map_ = new QAction(tr("Show on map"), this);
    menu_->addAction(show_on_map_);
    connect(show_on_map_, SIGNAL(triggered()),
            this,
            SLOT(activateLastNode()));
    focus_on_ = new QAction(tr("Focus on"), this);
    menu_->addAction(focus_on_);
    connect(focus_on_, SIGNAL(triggered()),
            this,
            SLOT(focusOnLastNode()));

    updateDrawRect();
  }
void TestResultDelegate::recalculateTextLayout(const QModelIndex &index, const QString &output,
                                               const QFont &font, int width) const
{
    if (m_lastProcessedIndex == index && m_lastProcessedFont == font)
        return;

    const QFontMetrics fm(font);
    const int leading = fm.leading();
    const int fontHeight = fm.height();

    m_lastProcessedIndex = index;
    m_lastProcessedFont = font;
    m_lastCalculatedHeight = 0;
    m_lastCalculatedLayout.clearLayout();
    m_lastCalculatedLayout.setText(output);
    m_lastCalculatedLayout.setFont(font);
    QTextOption txtOption;
    txtOption.setWrapMode(QTextOption::WrapAtWordBoundaryOrAnywhere);
    m_lastCalculatedLayout.setTextOption(txtOption);
    m_lastCalculatedLayout.beginLayout();
    while (true) {
        QTextLine line = m_lastCalculatedLayout.createLine();
        if (!line.isValid())
            break;
        line.setLineWidth(width);
        m_lastCalculatedHeight += leading;
        line.setPosition(QPoint(0, m_lastCalculatedHeight));
        m_lastCalculatedHeight += fontHeight;
    }
    m_lastCalculatedLayout.endLayout();
}
void PluginListDelegate::drawDisplay(QPainter* painter, const QStyleOptionViewItem &option, const QRect &rect, const QString &text) const
{
    QTextDocument textDocument;
    textDocument.setHtml(text);

    QTextLayout textLayout(textDocument.begin());
    textLayout.setFont(option.font);

    const int textMargin = QApplication::style()->pixelMetric(QStyle::PM_FocusFrameHMargin, 0) + 1;
    QRect textRect = rect.adjusted(textMargin, 0, -textMargin, 0); // remove width padding

    textLayout.beginLayout();
    qreal height = 0;
    while (1) {
        QTextLine line = textLayout.createLine();
        if (!line.isValid()) {
            break;
        }

        line.setLineWidth(textRect.width());
        height += 3;
        line.setPosition(QPoint(0, height));
        height += line.height();
    }
    textLayout.endLayout();

    textLayout.draw(painter, QPointF(textRect.left(), textRect.top()));
}
Exemple #5
0
QPixmap QDeclarativeTextPrivate::wrappedTextImage(bool drawStyle)
{
    //do layout
    QSize size = cachedLayoutSize;

    int x = 0;
    for (int i = 0; i < layout.lineCount(); ++i) {
        QTextLine line = layout.lineAt(i);
        if (hAlign == QDeclarativeText::AlignLeft) {
            x = 0;
        } else if (hAlign == QDeclarativeText::AlignRight) {
            x = size.width() - (int)line.naturalTextWidth();
        } else if (hAlign == QDeclarativeText::AlignHCenter) {
            x = (size.width() - (int)line.naturalTextWidth()) / 2;
        }
        line.setPosition(QPoint(x, (int)line.y()));
    }

    //paint text
    QPixmap img(size);
    if (!size.isEmpty()) {
        img.fill(Qt::transparent);
        QPainter p(&img);
        drawWrappedText(&p, QPointF(0,0), drawStyle);
    }
    return img;
}
Exemple #6
0
void paint_QTextLayout(QPainter &p, bool useCache)
{
    static bool first = true;
    static QTextLayout *textLayout[lines];
    if (first) {
        for (int i = 0; i < lines; ++i) {
            textLayout[i] = new QTextLayout(strings[i]);
            int leading = p.fontMetrics().leading();
            qreal height = 0;
            qreal widthUsed = 0;
            textLayout[i]->setCacheEnabled(useCache);
            textLayout[i]->beginLayout();
            while (1) {
                QTextLine line = textLayout[i]->createLine();
                if (!line.isValid())
                    break;

                line.setLineWidth(lineWidth);
                height += leading;
                line.setPosition(QPointF(0, height));
                height += line.height();
                widthUsed = qMax(widthUsed, line.naturalTextWidth());
            }
            textLayout[i]->endLayout();
        }
        first = false;
    }
    for (int i = 0; i < count; ++i) {
        for (int j = 0; j < lines; ++j) {
            textLayout[j]->draw(&p, QPoint(0, j*spacing));
        }
    }
}
Exemple #7
0
void YTDelegate::layoutText(QTextLayout& textLayout, QString text, QSize constraint) const
{
    QTextOption textOption(Qt::AlignJustify);
    textLayout.setTextOption(textOption);
    textLayout.setText(text);
    textLayout.beginLayout();
    int lHeight = 0;
    while(true){
        QTextLine line = textLayout.createLine();
        if(!line.isValid())
            break;
        line.setLineWidth(constraint.width());
        line.setPosition(QPointF(0, lHeight));
        if(lHeight + line.height() > constraint.height())
        {
            QTextLine lastLine = textLayout.lineAt(textLayout.lineCount() - 2);
            QString lastString = text.mid(lastLine.textStart());
            QFontMetrics fm(textLayout.font());
            text.chop(lastString.length());
            text += fm.elidedText(lastString, Qt::ElideRight, constraint.width()-1);
            textLayout.endLayout();
            layoutText(textLayout, text, constraint);
            return;
        }
        lHeight += line.height();
        lHeight += line.leading();
    }
    textLayout.endLayout();
}
//virtual
void	PixButton::redoLabelTextLayout()
{
	//TODO: somewhat wasteful. If there is no label, should just exit early and leave a layout that will be left unrendered by paint()
	m_textLayoutObject.clearLayout();
	m_textLayoutObject.setText(m_label);
	m_textLayoutObject.setFont(m_textFont);
	QTextOption textOpts;
	textOpts.setAlignment(Qt::AlignHCenter | Qt::AlignVCenter);
	textOpts.setWrapMode(QTextOption::WrapAtWordBoundaryOrAnywhere);
	m_textLayoutObject.setTextOption(textOpts);

	QFontMetrics textFontMetrics(m_textFont);
	int leading = textFontMetrics.leading();
	int rise = textFontMetrics.ascent();
	qreal height = 0;

	m_textLayoutObject.beginLayout();
	while (height < m_labelMaxGeom.height()) {
		QTextLine line = m_textLayoutObject.createLine();
		if (!line.isValid())
			break;
		line.setLineWidth(m_labelMaxGeom.width());
		if (m_textLayoutObject.lineCount() > 1)
		{
			height += leading;
		}
		line.setPosition(QPointF(0, height));
		height += line.height();
	}
	height = qMin((quint32)DimensionsGlobal::roundUp(height),(quint32)m_labelMaxGeom.height());
	height = DimensionsGlobal::roundDown(height) - (DimensionsGlobal::roundDown(height) % 2);	//force to an even #
	m_textLayoutObject.endLayout();
	//TODO: PIXEL-ALIGN
	m_labelGeom = DimensionsGlobal::realRectAroundRealPoint(QSizeF(m_textLayoutObject.boundingRect().width(),height)).toAlignedRect();
}
Exemple #9
0
QSize QDeclarativeTextPrivate::setupTextLayout(QTextLayout *layout)
{
    Q_Q(QDeclarativeText);
    layout->setCacheEnabled(true);

    int height = 0;
    qreal widthUsed = 0;
    qreal lineWidth = 0;

    //set manual width
    if ((wrap || elideMode != QDeclarativeText::ElideNone) && q->widthValid())
        lineWidth = q->width();

    layout->beginLayout();

    while (1) {
        QTextLine line = layout->createLine();
        if (!line.isValid())
            break;

        if ((wrap || elideMode != QDeclarativeText::ElideNone) && q->widthValid())
            line.setLineWidth(lineWidth);
    }
    layout->endLayout();

    int x = 0;
    for (int i = 0; i < layout->lineCount(); ++i) {
        QTextLine line = layout->lineAt(i);
        widthUsed = qMax(widthUsed, line.naturalTextWidth());
        line.setPosition(QPointF(0, height));
        height += int(line.height());

        if (!cache) {
            if (hAlign == QDeclarativeText::AlignLeft) {
                x = 0;
            } else if (hAlign == QDeclarativeText::AlignRight) {
                x = q->width() - (int)line.naturalTextWidth();
            } else if (hAlign == QDeclarativeText::AlignHCenter) {
                x = (q->width() - (int)line.naturalTextWidth()) / 2;
            }
            line.setPosition(QPoint(x, (int)line.y()));
        }
    }

    return QSize(qCeil(widthUsed), height);
}
Exemple #10
0
void ChatItem::doLayout(QTextLayout *layout) const {
  layout->beginLayout();
  QTextLine line = layout->createLine();
  if(line.isValid()) {
    line.setLineWidth(width());
    line.setPosition(QPointF(0,0));
  }
  layout->endLayout();
}
Exemple #11
0
void LayerView::setDisplayedName(const QString& s)
{
    m_displayedName = s;

    m_textcache.setText(s);
    m_textcache.beginLayout();
    QTextLine line = m_textcache.createLine();
    line.setPosition(QPointF{0., 0.});

    m_textcache.endLayout();

    update();
}
// Origin: Qt
static void viewItemTextLayout ( QTextLayout &textLayout, int lineWidth, qreal &height, qreal &widthUsed )
{
	height = 0;
	widthUsed = 0;
	textLayout.beginLayout();
	while ( true )
	{
		QTextLine line = textLayout.createLine();
		if ( !line.isValid() )
			break;
		line.setLineWidth ( lineWidth );
		line.setPosition ( QPointF ( 0, height ) );
		height += line.height();
		widthUsed = qMax ( widthUsed, line.naturalTextWidth() );
	}
	textLayout.endLayout();
}
// copied from QItemDelegate for drawDisplay
QSizeF doTextLayout(QTextLayout *textLayout, int lineWidth)
{
    qreal height = 0;
    qreal widthUsed = 0;
    textLayout->beginLayout();
    while (true) {
        QTextLine line = textLayout->createLine();
        if (!line.isValid())
            break;
        line.setLineWidth(lineWidth);
        line.setPosition(QPointF(0, height));
        height += line.height();
        widthUsed = qMax(widthUsed, line.naturalTextWidth());
    }
    textLayout->endLayout();
    return QSizeF(widthUsed, height);
}
Exemple #14
0
static int layoutText(QTextLayout *layout, int maxWidth) {
    qreal height = 0;
    int textWidth = 0;
    layout->beginLayout();
    while (true) {
        QTextLine line = layout->createLine();
        if (!line.isValid()) {
            break;
        }
        line.setLineWidth(maxWidth);
        line.setPosition(QPointF(0, height));
        height += line.height();
        textWidth = qMax(textWidth, qRound(line.naturalTextWidth() + 0.5));
    }
    layout->endLayout();
    return textWidth;
}
Exemple #15
0
QSizeF QItemDelegatePrivate::doTextLayout(int lineWidth) const
{
    qreal height = 0;
    qreal widthUsed = 0;
    textLayout.beginLayout();
    while (true) {
        QTextLine line = textLayout.createLine();
        if (!line.isValid())
            break;
        line.setLineWidth(lineWidth);
        line.setPosition(QPointF(0, height));
        height += line.height();
        widthUsed = qMax(widthUsed, line.naturalTextWidth());
    }
    textLayout.endLayout();
    return QSizeF(widthUsed, height);
}
void Window::paintEvent(QPaintEvent *event)
{
//! [0]
    QTextLayout textLayout(text, font);
    qreal margin = 10;
    qreal radius = qMin(width()/2.0, height()/2.0) - margin;
    QFontMetrics fm(font);

    qreal lineHeight = fm.height();
    qreal y = 0;

    textLayout.beginLayout();

    while (1) {
        // create a new line 
        QTextLine line = textLayout.createLine();
        if (!line.isValid())
            break;

        qreal x1 = qMax(0.0, pow(pow(radius,2)-pow(radius-y,2), 0.5));
        qreal x2 = qMax(0.0, pow(pow(radius,2)-pow(radius-(y+lineHeight),2), 0.5));
        qreal x = qMax(x1, x2) + margin;
        qreal lineWidth = (width() - margin) - x;

        line.setLineWidth(lineWidth);
        line.setPosition(QPointF(x, margin+y));
        y += line.height();
    }

    textLayout.endLayout();

    QPainter painter;
    painter.begin(this);
    painter.setRenderHint(QPainter::Antialiasing);
    painter.fillRect(rect(), Qt::white);
    painter.setBrush(QBrush(Qt::black));
    painter.setPen(QPen(Qt::black));
    textLayout.draw(&painter, QPoint(0,0));

    painter.setBrush(QBrush(QColor("#a6ce39")));
    painter.setPen(QPen(Qt::black));
    painter.drawEllipse(QRectF(-radius, margin, 2*radius, 2*radius));
    painter.end();
//! [0]
}
qreal QmlConsoleItemDelegate::layoutText(QTextLayout &tl, int width,
                                         bool *showFileLineInfo) const
{
    qreal height = 0;
    tl.beginLayout();
    while (true) {
        QTextLine line = tl.createLine();

        if (!line.isValid())
            break;
        line.setLeadingIncluded(true);
        line.setLineWidth(width);
        if (width < line.naturalTextWidth() && showFileLineInfo)
            *showFileLineInfo = false;
        line.setPosition(QPoint(0, height));
        height += line.height();
    }
    tl.endLayout();
    return height;
}
void StyledLabel::layout()
{
    qreal h = 0;
    qreal w = contentsRect().width();

    _layout.beginLayout();
    forever {
        QTextLine line = _layout.createLine();
        if (!line.isValid())
            break;
        line.setLineWidth(w);
        line.setPosition(QPointF(0, h));
        h += line.height();
    }
    _layout.endLayout();

    updateSizeHint();
    updateToolTip();
    update();
}
void PluginListDelegate::drawDisplay(QPainter* painter, const QStyleOptionViewItem &option, const QRect &rect, const QString &text) const
{
    QPalette::ColorGroup cg = option.state & QStyle::State_Enabled ? QPalette::Normal : QPalette::Disabled;

    if (cg == QPalette::Normal && !(option.state & QStyle::State_Active)) {
        cg = QPalette::Inactive;
    }

    if (option.state & QStyle::State_Selected) {
        painter->fillRect(rect, option.palette.brush(cg, QPalette::Highlight));
        painter->setPen(option.palette.color(cg, QPalette::HighlightedText));
    }
    else {
        painter->setPen(option.palette.color(cg, QPalette::Text));
    }

    QTextDocument textDocument;
    textDocument.setHtml(text);

    QTextLayout textLayout(textDocument.begin());
    textLayout.setFont(option.font);

    const int textMargin = QApplication::style()->pixelMetric(QStyle::PM_FocusFrameHMargin, 0) + 1;
    QRect textRect = rect.adjusted(textMargin, 0, -textMargin, 0); // remove width padding

    textLayout.beginLayout();
    qreal height = 0;
    QTextLine line = textLayout.createLine();

    while (line.isValid()) {
        line.setLineWidth(textRect.width());
        height += 3;
        line.setPosition(QPoint(0, height));
        height += line.height();

        line = textLayout.createLine();
    }

    textLayout.endLayout();
    textLayout.draw(painter, QPointF(textRect.left(), textRect.top()));
}
Exemple #20
0
//virtual
void	PageTab::redoLabelTextLayout()
{
	//TODO: somewhat wasteful. If there is no label, should just exit early and leave a layout that will be left unrendered by paint()
	m_textLayoutObject.clearLayout();;
	//TODO: Need a real fix later instead of localizing the labels at runtime
	QString m_tabLabelLocalized = fromStdUtf8(LOCALIZED(m_tabLabel.toStdString()));
	m_textLayoutObject.setText(m_tabLabelLocalized);

//	int fontSize = qBound(4,(int)((qreal)(m_labelMaxGeom.height())*0.5),24) -2;
//	fontSize = fontSize - (fontSize % 2);
//	m_textFont.setPixelSize(fontSize);
	m_textLayoutObject.setFont(m_textFont);
	QTextOption textOpts;
	textOpts.setAlignment(Qt::AlignHCenter | Qt::AlignVCenter);
	textOpts.setWrapMode(QTextOption::WrapAtWordBoundaryOrAnywhere);
	m_textLayoutObject.setTextOption(textOpts);

	QFontMetrics textFontMetrics(m_textFont);
	int leading = textFontMetrics.leading();
	int rise = textFontMetrics.ascent();
	qreal height = 0;

	m_textLayoutObject.beginLayout();
	while (height < m_labelMaxGeom.height()) {
		QTextLine line = m_textLayoutObject.createLine();
		if (!line.isValid())
			break;
		line.setLineWidth(m_labelMaxGeom.width());
		if (m_textLayoutObject.lineCount() > 1)
		{
			height += leading;
		}
		line.setPosition(QPointF(0, height));
		height += line.height();
	}
	height = qMin((quint32)DimensionsGlobal::roundUp(height),(quint32)m_labelMaxGeom.height());
	height = DimensionsGlobal::roundDown(height) - (DimensionsGlobal::roundDown(height) % 2);	//force to an even #
	m_textLayoutObject.endLayout();
	//TODO: PIXEL-ALIGN
	m_labelGeom = DimensionsGlobal::realRectAroundRealPoint(QSizeF(m_textLayoutObject.boundingRect().width(),height)).toAlignedRect();
}
Exemple #21
0
// Calculates the height of the description text based on widget width
int QCommandLinkButtonPrivate::descriptionHeight(int widgetWidth) const
{
    // Calc width of actual paragraph
    int lineWidth = widgetWidth - textOffset() - rightMargin();

    qreal descriptionheight = 0;
    if (!description.isEmpty()) {
        QTextLayout layout(description);
        layout.setFont(descriptionFont());
        layout.beginLayout();
        while (true) {
            QTextLine line = layout.createLine();
            if (!line.isValid())
                break;
            line.setLineWidth(lineWidth);
            line.setPosition(QPointF(0, descriptionheight));
            descriptionheight += line.height();
        }
        layout.endLayout();
    }
    return qRound(descriptionheight);
}
void FadingMultilineLabel::positionLayouts()
{
	QFontMetricsF fm = fontMetrics();
	qreal lineHeight = fm.height();

	delete textLayout_;
	textLayout_ = 0;

	textLayout_ = new QTextLayout(text_, font());
	textLayout_->setTextOption(textOption_);
	// textLayout_->setAdditionalFormats(formats[p]);
	textLayout_->beginLayout();

	qreal x = 0.0;
	qreal y = 0.0;
	qreal ymax = 0.0;

	fadeOuts_.clear();
	QTextLine line = textLayout_->createLine();

	while (line.isValid()) {
		line.setPosition(QPointF(x, y));
		line.setLineWidth(width());

		if (line.naturalTextWidth() > width()) {
			fadeOuts_ << QRect(x, y, width(), lineHeight);
		}

		y += line.height();
		line = textLayout_->createLine();
	}

	textLayout_->endLayout();

	sizeHint_ = QSize(width(), y);
	updateGeometry();
}
Exemple #23
0
QSize TaskDelegate::sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const
{
    QStyleOptionViewItemV4 opt = option;
    initStyleOption(&opt, index);


    QFontMetrics fm(option.font);
    QSize s;
    s.setWidth(option.rect.width());
    const QAbstractItemView * view = qobject_cast<const QAbstractItemView *>(opt.widget);
    TaskModel *model = static_cast<TaskModel *>(view->model());
    int width = opt.rect.width() - model->sizeOfFile() - model->sizeOfLineNumber() - 12 - 22;
    if (view->selectionModel()->currentIndex() == index) {
        QString description = index.data(TaskModel::Description).toString();
        // Layout the description
        int leading = fm.leading();
        int height = 0;
        QTextLayout tl(description);
        tl.beginLayout();
        while (true) {
            QTextLine line = tl.createLine();
            if (!line.isValid())
                break;
            line.setLineWidth(width);
            height += leading;
            line.setPosition(QPoint(0, height));
            height += static_cast<int>(line.height());
        }
        tl.endLayout();

        s.setHeight(height + leading + fm.height() + 3);
    } else {
        s.setHeight(fm.height() + 3);
    }
    return s;
}
Exemple #24
0
void Msg::ShowMsg(const QString str)
{
    mUpdateRect = boundingRect();

    mLay->setText(str);
    int leading = -3;
    qreal h = 0;
    qreal maxw = 0;
    qreal maxh = 0;
    mLay->beginLayout();

    while (1)
    {
        QTextLine line = mLay->createLine();
        if (!line.isValid())
        {
            break;
        }

        line.setLineWidth(280);
        h += leading;
        line.setPosition(QPointF(0, h));
        h += line.height();
        maxw = qMax(maxw, line.naturalTextWidth());
    }
    mLay->endLayout();

    float ypos = 4 + (70 - mLay->boundingRect().height()) / 2;

    maxw = qMax(mUpdateRect.width(), mLay->boundingRect().width());
    maxh = qMax(mUpdateRect.height(), mLay->boundingRect().height() + ypos);

    mUpdateRect = QRectF(0, 0, maxw, maxh + ypos);

    update(boundingRect());
}
Exemple #25
0
void QStaticTextPrivate::paintText(const QPointF &topLeftPosition, QPainter *p)
{
    bool preferRichText = textFormat == Qt::RichText
                          || (textFormat == Qt::AutoText && Qt::mightBeRichText(text));

    if (!preferRichText) {
        QTextLayout textLayout;
        textLayout.setText(text);
        textLayout.setFont(font);
        textLayout.setTextOption(textOption);

        qreal leading = QFontMetricsF(font).leading();
        qreal height = -leading;

        textLayout.beginLayout();
        while (1) {
            QTextLine line = textLayout.createLine();
            if (!line.isValid())
                break;

            if (textWidth >= 0.0)
                line.setLineWidth(textWidth);
            height += leading;
            line.setPosition(QPointF(0.0, height));
            height += line.height();
        }
        textLayout.endLayout();

        actualSize = textLayout.boundingRect().size();
        textLayout.draw(p, topLeftPosition);
    } else {
        QTextDocument document;
#ifndef QT_NO_CSSPARSER
        QColor color = p->pen().color();
        document.setDefaultStyleSheet(QString::fromLatin1("body { color: #%1%2%3 }")
                                      .arg(QString::number(color.red(), 16), 2, QLatin1Char('0'))
                                      .arg(QString::number(color.green(), 16), 2, QLatin1Char('0'))
                                      .arg(QString::number(color.blue(), 16), 2, QLatin1Char('0')));
#endif
        document.setDefaultFont(font);
        document.setDocumentMargin(0.0);        
#ifndef QT_NO_TEXTHTMLPARSER
        document.setHtml(text);
#else
        document.setPlainText(text);
#endif
        if (textWidth >= 0.0)
            document.setTextWidth(textWidth);
        else
            document.adjustSize();
        document.setDefaultTextOption(textOption);

        p->save();
        p->translate(topLeftPosition);
        QAbstractTextDocumentLayout::PaintContext ctx;
        ctx.palette.setColor(QPalette::Text, p->pen().color());
        document.documentLayout()->draw(p, ctx);
        p->restore();

        if (textWidth >= 0.0)
            document.adjustSize(); // Find optimal size

        actualSize = document.size();
    }
}
Exemple #26
0
void QSvgText::draw(QPainter *p, QSvgExtraStates &states)
{
    applyStyle(p, states);
    qreal oldOpacity = p->opacity();
    p->setOpacity(oldOpacity * states.fillOpacity);

    // Force the font to have a size of 100 pixels to avoid truncation problems
    // when the font is very small.
    qreal scale = 100.0 / p->font().pointSizeF();
    Qt::Alignment alignment = states.textAnchor;

    QTransform oldTransform = p->worldTransform();
    p->scale(1 / scale, 1 / scale);

    qreal y = 0;
    bool initial = true;
    qreal px = m_coord.x() * scale;
    qreal py = m_coord.y() * scale;
    QSizeF scaledSize = m_size * scale;

    if (m_type == TEXTAREA) {
        if (alignment == Qt::AlignHCenter)
            px += scaledSize.width() / 2;
        else if (alignment == Qt::AlignRight)
            px += scaledSize.width();
    }

    QRectF bounds;
    if (m_size.height() != 0)
        bounds = QRectF(0, py, 1, scaledSize.height()); // x and width are not used.

    bool appendSpace = false;
    QVector<QString> paragraphs;
    QStack<QTextCharFormat> formats;
    QVector<QList<QTextLayout::FormatRange> > formatRanges;
    paragraphs.push_back(QString());
    formatRanges.push_back(QList<QTextLayout::FormatRange>());

    for (int i = 0; i < m_tspans.size(); ++i) {
        if (m_tspans[i] == LINEBREAK) {
            if (m_type == TEXTAREA) {
                if (paragraphs.back().isEmpty()) {
                    QFont font = p->font();
                    font.setPixelSize(font.pointSizeF() * scale);

                    QTextLayout::FormatRange range;
                    range.start = 0;
                    range.length = 1;
                    range.format.setFont(font);
                    formatRanges.back().append(range);

                    paragraphs.back().append(QLatin1Char(' '));;
                }
                appendSpace = false;
                paragraphs.push_back(QString());
                formatRanges.push_back(QList<QTextLayout::FormatRange>());
            }
        } else {
            WhitespaceMode mode = m_tspans[i]->whitespaceMode();
            m_tspans[i]->applyStyle(p, states);

            QFont font = p->font();
            font.setPixelSize(font.pointSizeF() * scale);

            QString newText(m_tspans[i]->text());
            newText.replace(QLatin1Char('\t'), QLatin1Char(' '));
            newText.replace(QLatin1Char('\n'), QLatin1Char(' '));

            bool prependSpace = !appendSpace && !m_tspans[i]->isTspan() && (mode == Default) && !paragraphs.back().isEmpty() && newText.startsWith(QLatin1Char(' '));
            if (appendSpace || prependSpace)
                paragraphs.back().append(QLatin1Char(' '));

            bool appendSpaceNext = (!m_tspans[i]->isTspan() && (mode == Default) && newText.endsWith(QLatin1Char(' ')));

            if (mode == Default) {
                newText = newText.simplified();
                if (newText.isEmpty())
                    appendSpaceNext = false;
            }

            QTextLayout::FormatRange range;
            range.start = paragraphs.back().length();
            range.length = newText.length();
            range.format.setFont(font);
            range.format.setTextOutline(p->pen());
            range.format.setForeground(p->brush());

            if (appendSpace) {
                Q_ASSERT(!formatRanges.back().isEmpty());
                ++formatRanges.back().back().length;
            } else if (prependSpace) {
                --range.start;
                ++range.length;
            }
            formatRanges.back().append(range);

            appendSpace = appendSpaceNext;
            paragraphs.back() += newText;

            m_tspans[i]->revertStyle(p, states);
        }
    }

    if (states.svgFont) {
        // SVG fonts not fully supported...
        QString text = paragraphs.front();
        for (int i = 1; i < paragraphs.size(); ++i) {
            text.append(QLatin1Char('\n'));
            text.append(paragraphs[i]);
        }
        states.svgFont->draw(p, m_coord * scale, text, p->font().pointSizeF() * scale, states.textAnchor);
    } else {
        for (int i = 0; i < paragraphs.size(); ++i) {
            QTextLayout tl(paragraphs[i]);
            QTextOption op = tl.textOption();
            op.setWrapMode(QTextOption::WrapAtWordBoundaryOrAnywhere);
            tl.setTextOption(op);
            tl.setAdditionalFormats(formatRanges[i]);
            tl.beginLayout();

            forever {
                QTextLine line = tl.createLine();
                if (!line.isValid())
                    break;
                if (m_size.width() != 0)
                    line.setLineWidth(scaledSize.width());
            }
            tl.endLayout();

            bool endOfBoundsReached = false;
            for (int i = 0; i < tl.lineCount(); ++i) {
                QTextLine line = tl.lineAt(i);

                qreal x = 0;
                if (alignment == Qt::AlignHCenter)
                    x -= 0.5 * line.naturalTextWidth();
                else if (alignment == Qt::AlignRight)
                    x -= line.naturalTextWidth();

                if (initial && m_type == TEXT)
                    y -= line.ascent();
                initial = false;

                line.setPosition(QPointF(x, y));

                // Check if the current line fits into the bounding rectangle.
                if ((m_size.width() != 0 && line.naturalTextWidth() > scaledSize.width())
                    || (m_size.height() != 0 && y + line.height() > scaledSize.height())) {
                    // I need to set the bounds height to 'y-epsilon' to avoid drawing the current
                    // line. Since the font is scaled to 100 units, 1 should be a safe epsilon.
                    bounds.setHeight(y - 1);
                    endOfBoundsReached = true;
                    break;
                }

                y += 1.1 * line.height();
            }
            tl.draw(p, QPointF(px, py), QVector<QTextLayout::FormatRange>(), bounds);

            if (endOfBoundsReached)
                break;
        }
    }

    p->setWorldTransform(oldTransform, false);
    p->setOpacity(oldOpacity);
    revertStyle(p, states);
}
void DTPatientListDelegate::drawHightlightText(QPainter *painter,
                                               QString text,
                                               QString substring,
                                               QRect pos,
                                               Qt::CaseSensitivity cs,
                                               bool boldFont,
                                               QColor highlight) const
{
    if (!painter || (text.length() == 0))
        return;

    painter->save();
    QVector<QTextLayout::FormatRange> selections;
    QTextLayout textLayout;
    textLayout.setText(text);

    if (substring.length() != 0)
    {
        int idx = -1;
        int start = 0;
        while (1)
        {
            idx = text.indexOf(substring, start,cs);
            if (idx == -1)
                break;

            QTextLayout::FormatRange* range = new QTextLayout::FormatRange;
            range->start = idx;
            range->length = substring.length();
            range->format.setBackground(QBrush(QColor(highlight)));
            selections.append(*range);
            start += substring.length();
        }
    }

    if (boldFont)
    {
        QFont f = textLayout.font();
        f.setBold(true);
        textLayout.setFont(f);
    }

    int leading = painter->fontMetrics().leading();
    qreal height = 0;
    textLayout.beginLayout();
    while (1) {
        QTextLine line = textLayout.createLine();
        if (!line.isValid())
            break;

        line.setLineWidth(pos.width());
        height += leading;
        line.setPosition(QPointF(0, height));
        height += line.height();
    }
    textLayout.endLayout();

    textLayout.draw(painter, pos.topLeft(), selections);

    painter->restore();

}
void TextDocumentLayout::layoutBlock(const QTextBlock &block)
{
    QTextDocument *doc = document();
    qreal margin = doc->documentMargin();
    qreal blockMaximumWidth = 0;

    qreal height = 0;
    QTextLayout *tl = block.layout();
    QTextOption option = doc->defaultTextOption();
    tl->setTextOption(option);

    int extraMargin = 0;
    if (option.flags() & QTextOption::AddSpaceForLineAndParagraphSeparators) {
        QFontMetrics fm(block.charFormat().font());
        extraMargin += fm.width(QChar(0x21B5));
    }
    tl->beginLayout();
    qreal availableWidth = d->width;
    if (availableWidth <= 0) {
        availableWidth = qreal(INT_MAX); // similar to text edit with pageSize.width == 0
    }
    availableWidth -= 2*margin + extraMargin;
    qreal indentMargin = 0;
    while (1) {
        QTextLine line = tl->createLine();
        if (!line.isValid())
            break;
        line.setLeadingIncluded(true);
        line.setLineWidth(availableWidth - indentMargin);
        line.setPosition(QPointF(margin + indentMargin, height));
        if(!height) //enter only in the first iteration
        {
            indentMargin = indentWidth(block);
        }
        height += line.height();
        blockMaximumWidth = qMax(blockMaximumWidth, line.naturalTextWidth() + 2*margin);
    }
    tl->endLayout();

    int previousLineCount = doc->lineCount();
    const_cast<QTextBlock&>(block).setLineCount(block.isVisible() ? tl->lineCount() : 0);
    int lineCount = doc->lineCount();

    bool emitDocumentSizeChanged = previousLineCount != lineCount;
    if (blockMaximumWidth > d->maximumWidth) {
        // new longest line
        d->maximumWidth = blockMaximumWidth;
        d->maximumWidthBlockNumber = block.blockNumber();
        emitDocumentSizeChanged = true;
    } else if (block.blockNumber() == d->maximumWidthBlockNumber && blockMaximumWidth < d->maximumWidth) {
        // longest line shrinking
        QTextBlock b = doc->firstBlock();
        d->maximumWidth = 0;
        QTextBlock maximumBlock;
        while (b.isValid()) {
            qreal blockMaximumWidth = blockWidth(b);
            if (blockMaximumWidth > d->maximumWidth) {
                d->maximumWidth = blockMaximumWidth;
                maximumBlock = b;
            }
            b = b.next();
        }
        if (maximumBlock.isValid()) {
            d->maximumWidthBlockNumber = maximumBlock.blockNumber();
            emitDocumentSizeChanged = true;
        }
    }
    if (emitDocumentSizeChanged)// && !d->blockDocumentSizeChanged)
        emit documentSizeChanged(documentSize());

    emit updateBlock(block);
}
void QQuickTextNodeEngine::addTextBlock(QTextDocument *textDocument, const QTextBlock &block, const QPointF &position, const QColor &textColor, const QColor &anchorColor, int selectionStart, int selectionEnd)
{
    Q_ASSERT(textDocument);
#ifndef QT_NO_IM
    int preeditLength = block.isValid() ? block.layout()->preeditAreaText().length() : 0;
    int preeditPosition = block.isValid() ? block.layout()->preeditAreaPosition() : -1;
#endif

    QVarLengthArray<QTextLayout::FormatRange> colorChanges;
    mergeFormats(block.layout(), &colorChanges);

    QPointF blockPosition = textDocument->documentLayout()->blockBoundingRect(block).topLeft() + position;
    if (QTextList *textList = block.textList()) {
        QPointF pos = blockPosition;
        QTextLayout *layout = block.layout();
        if (layout->lineCount() > 0) {
            QTextLine firstLine = layout->lineAt(0);
            Q_ASSERT(firstLine.isValid());

            setCurrentLine(firstLine);

            QRectF textRect = firstLine.naturalTextRect();
            pos += textRect.topLeft();
            if (block.textDirection() == Qt::RightToLeft)
                pos.rx() += textRect.width();

            const QTextCharFormat charFormat = block.charFormat();
            QFont font(charFormat.font());
            QFontMetricsF fontMetrics(font);
            QTextListFormat listFormat = textList->format();

            QString listItemBullet;
            switch (listFormat.style()) {
            case QTextListFormat::ListCircle:
                listItemBullet = QChar(0x25E6); // White bullet
                break;
            case QTextListFormat::ListSquare:
                listItemBullet = QChar(0x25AA); // Black small square
                break;
            case QTextListFormat::ListDecimal:
            case QTextListFormat::ListLowerAlpha:
            case QTextListFormat::ListUpperAlpha:
            case QTextListFormat::ListLowerRoman:
            case QTextListFormat::ListUpperRoman:
                listItemBullet = textList->itemText(block);
                break;
            default:
                listItemBullet = QChar(0x2022); // Black bullet
                break;
            };

            QSizeF size(fontMetrics.width(listItemBullet), fontMetrics.height());
            qreal xoff = fontMetrics.width(QLatin1Char(' '));
            if (block.textDirection() == Qt::LeftToRight)
                xoff = -xoff - size.width();
            setPosition(pos + QPointF(xoff, 0));

            QTextLayout layout;
            layout.setFont(font);
            layout.setText(listItemBullet); // Bullet
            layout.beginLayout();
            QTextLine line = layout.createLine();
            line.setPosition(QPointF(0, 0));
            layout.endLayout();

            QList<QGlyphRun> glyphRuns = layout.glyphRuns();
            for (int i=0; i<glyphRuns.size(); ++i)
                addUnselectedGlyphs(glyphRuns.at(i));
        }
    }

    int textPos = block.position();
    QTextBlock::iterator blockIterator = block.begin();

    while (!blockIterator.atEnd()) {
        QTextFragment fragment = blockIterator.fragment();
        QString text = fragment.text();
        if (text.isEmpty())
            continue;

        QTextCharFormat charFormat = fragment.charFormat();
        QFont font(charFormat.font());
        QFontMetricsF fontMetrics(font);

        int fontHeight = fontMetrics.descent() + fontMetrics.ascent();
        int valign = charFormat.verticalAlignment();
        if (valign == QTextCharFormat::AlignSuperScript)
            setPosition(QPointF(blockPosition.x(), blockPosition.y() - fontHeight / 2));
        else if (valign == QTextCharFormat::AlignSubScript)
            setPosition(QPointF(blockPosition.x(), blockPosition.y() + fontHeight / 6));
        else
            setPosition(blockPosition);

        if (text.contains(QChar::ObjectReplacementCharacter)) {
            QTextFrame *frame = qobject_cast<QTextFrame *>(textDocument->objectForFormat(charFormat));
            if (frame && frame->frameFormat().position() == QTextFrameFormat::InFlow) {
                int blockRelativePosition = textPos - block.position();
                QTextLine line = block.layout()->lineForTextPosition(blockRelativePosition);
                if (!currentLine().isValid()
                        || line.lineNumber() != currentLine().lineNumber()) {
                    setCurrentLine(line);
                }

                QQuickTextNodeEngine::SelectionState selectionState =
                        (selectionStart < textPos + text.length()
                         && selectionEnd >= textPos)
                        ? QQuickTextNodeEngine::Selected
                        : QQuickTextNodeEngine::Unselected;

                addTextObject(QPointF(), charFormat, selectionState, textDocument, textPos);
            }
            textPos += text.length();
        } else {
            if (charFormat.foreground().style() != Qt::NoBrush)
                setTextColor(charFormat.foreground().color());
            else if (charFormat.isAnchor())
                setTextColor(anchorColor);
            else
                setTextColor(textColor);

            int fragmentEnd = textPos + fragment.length();
#ifndef QT_NO_IM
            if (preeditPosition >= 0
                    && (preeditPosition + block.position()) >= textPos
                    && (preeditPosition + block.position()) <= fragmentEnd) {
                fragmentEnd += preeditLength;
            }
#endif
            if (charFormat.background().style() != Qt::NoBrush) {
                QTextLayout::FormatRange additionalFormat;
                additionalFormat.start = textPos - block.position();
                additionalFormat.length = fragmentEnd - textPos;
                additionalFormat.format = charFormat;
                colorChanges << additionalFormat;
            }

            textPos = addText(block, charFormat, textColor, colorChanges, textPos, fragmentEnd,
                                                 selectionStart, selectionEnd);
        }

        ++blockIterator;
    }

#ifndef QT_NO_IM
    if (preeditLength >= 0 && textPos <= block.position() + preeditPosition) {
        setPosition(blockPosition);
        textPos = block.position() + preeditPosition;
        QTextLine line = block.layout()->lineForTextPosition(preeditPosition);
        if (!currentLine().isValid()
                || line.lineNumber() != currentLine().lineNumber()) {
            setCurrentLine(line);
        }
        textPos = addText(block, block.charFormat(), textColor, colorChanges,
                                             textPos, textPos + preeditLength,
                                             selectionStart, selectionEnd);
    }
#endif

    setCurrentLine(QTextLine()); // Reset current line because the text layout changed
    m_hasContents = true;
}
// FIXME: we need to figure out a way to derive from Fm::FolderItemDelegate to avoid code duplication.
void DesktopItemDelegate::paint(QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index) const {
  Q_ASSERT(index.isValid());
  QStyleOptionViewItemV4 opt = option;
  initStyleOption(&opt, index);

  painter->save();
  painter->setClipRect(option.rect);

  opt.decorationAlignment = Qt::AlignHCenter | Qt::AlignTop;
  opt.displayAlignment = Qt::AlignTop | Qt::AlignHCenter;

  // draw the icon
  QIcon::Mode iconMode;
  if(opt.state & QStyle::State_Enabled) {
    if(opt.state & QStyle::State_Selected)
      iconMode = QIcon::Selected;
    else {
      iconMode = QIcon::Normal;
    }
  }
  else
    iconMode = QIcon::Disabled;
  QPoint iconPos(opt.rect.x() + (opt.rect.width() - opt.decorationSize.width()) / 2, opt.rect.y());
  QPixmap pixmap = opt.icon.pixmap(opt.decorationSize, iconMode);
  painter->drawPixmap(iconPos, pixmap);

  // draw some emblems for the item if needed
  // we only support symlink emblem at the moment
  FmFileInfo* file = static_cast<FmFileInfo*>(index.data(Fm::FolderModel::FileInfoRole).value<void*>());
  if(file) {
    if(fm_file_info_is_symlink(file)) {
      painter->drawPixmap(iconPos, symlinkIcon_.pixmap(opt.decorationSize / 2, iconMode));
    }
  }

  // draw text
  QRectF textRect(opt.rect.x(), opt.rect.y() + opt.decorationSize.height(), opt.rect.width(), opt.rect.height() - opt.decorationSize.height());
  QTextLayout layout(opt.text, opt.font);

  QTextOption textOption;
  textOption.setAlignment(opt.displayAlignment);
  textOption.setWrapMode(QTextOption::WrapAtWordBoundaryOrAnywhere);
  textOption.setTextDirection(opt.direction);
  layout.setTextOption(textOption);
  qreal height = 0;
  qreal width = 0;
  int visibleLines = 0;
  layout.beginLayout();
  QString elidedText;

  for(;;) {
    QTextLine line = layout.createLine();
    if(!line.isValid())
      break;
    line.setLineWidth(textRect.width());
    height += opt.fontMetrics.leading();
    line.setPosition(QPointF(0, height));
    if((height + line.height() + textRect.y()) > textRect.bottom()) {
      // if part of this line falls outside the textRect, ignore it and quit.
      QTextLine lastLine = layout.lineAt(visibleLines - 1);
      elidedText = opt.text.mid(lastLine.textStart());
      elidedText = opt.fontMetrics.elidedText(elidedText, opt.textElideMode, textRect.width());
      break;
    }
    height += line.height();
    width = qMax(width, line.naturalTextWidth());
    ++ visibleLines;
  }
  layout.endLayout();
  QRectF boundRect = layout.boundingRect();
  boundRect.setWidth(width);
  boundRect.moveTo(textRect.x() + (textRect.width() - width)/2, textRect.y());
  if((opt.state & QStyle::State_Selected) && opt.widget) {
    QPalette palette = opt.widget->palette();
    // qDebug("w: %f, h:%f, m:%f", boundRect.width(), boundRect.height(), layout.minimumWidth());
    painter->fillRect(boundRect, palette.highlight());
  }
  else { // only draw shadow for non-selected items
    // draw shadow, FIXME: is it possible to use QGraphicsDropShadowEffect here?
    QPen prevPen = painter->pen();
    painter->setPen(QPen(shadowColor_));
    for(int i = 0; i < visibleLines; ++i) {
      QTextLine line = layout.lineAt(i);
      if(i == (visibleLines - 1) && !elidedText.isEmpty()) { // the last line, draw elided text
        QPointF pos(textRect.x() + line.position().x() + 1, textRect.y() + line.y() + line.ascent() + 1);
        painter->drawText(pos, elidedText);
      }
      else {
        line.draw(painter, textRect.topLeft() + QPointF(1, 1));
      }
    }
    painter->setPen(prevPen);
  }

  // draw text
  for(int i = 0; i < visibleLines; ++i) {
    QTextLine line = layout.lineAt(i);
    if(i == (visibleLines - 1) && !elidedText.isEmpty()) { // the last line, draw elided text
      QPointF pos(textRect.x() + line.position().x(), textRect.y() + line.y() + line.ascent());
      painter->drawText(pos, elidedText);
    }
    else {
      line.draw(painter, textRect.topLeft());
    }
  }

  if(opt.state & QStyle::State_HasFocus) {
    // FIXME: draw focus rect
  }
  painter->restore();
}