void KTextDocumentLayout::Private::adjustSize() { if (parent->resizeMethod() == KTextDocument::NoResize) return; if (parent->shapes().isEmpty()) return; // Limit auto-resizing to the first shape only (there won't be more // with auto-resizing turned on, unless specifically set) KShape *shape = parent->shapes().first(); // Determine the maximum width of all text lines qreal width = 0; for (QTextBlock block = parent->document()->begin(); block.isValid(); block = block.next()) { // The block layout's wrap mode must be QTextOption::NoWrap, thus the line count // of a valid block must be 1 (otherwise this resizing scheme wouldn't work) Q_ASSERT(block.layout()->lineCount() == 1); QTextLine line = block.layout()->lineAt(0); width = qMax(width, line.naturalTextWidth()); } // Use position and height of last text line to calculate height QTextLine line = parent->document()->lastBlock().layout()->lineAt(0); qreal height = line.position().y() + line.height(); shape->setSize(QSizeF(width, height)); }
QList<QGlyphRun> QTextFragment::glyphRuns(int pos, int len) const { if (!p || !n) return QList<QGlyphRun>(); int blockNode = p->blockMap().findNode(position()); const QTextBlockData *blockData = p->blockMap().fragment(blockNode); QTextLayout *layout = blockData->layout; int blockPosition = p->blockMap().position(blockNode); if (pos < 0) pos = position() - blockPosition; if (len < 0) len = length(); if (len == 0) return QList<QGlyphRun>(); QList<QGlyphRun> ret; for (int i=0; i<layout->lineCount(); ++i) { QTextLine textLine = layout->lineAt(i); ret += textLine.glyphRuns(pos, len); } return ret; }
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; }
void TestDocumentLayout::testRightToLeftList() { initForNewTest("a\nb\nc"); KoParagraphStyle h1; h1.setTextProgressionDirection(KoText::RightLeftTopBottom); m_styleManager->add(&h1); KoListStyle listStyle; KoListLevelProperties llp = listStyle.levelProperties(1); llp.setStyle(KoListStyle::DecimalItem); listStyle.setLevelProperties(llp); h1.setListStyle(&listStyle); QTextBlock block = m_doc->begin(); h1.applyStyle(block); block = block.next(); h1.applyStyle(block); block = block.next(); h1.applyStyle(block); block = block.next(); m_layout->layout(); block = m_doc->begin(); while (block.isValid()) { KoTextBlockData *data = dynamic_cast<KoTextBlockData *>(block.userData()); QVERIFY(data); QVERIFY(data->counterWidth() > 2); QVERIFY(data->counterPosition().x() > 100); QTextLine line = block.layout()->lineAt(0); QVERIFY(line.isValid()); QCOMPARE(line.x(), (qreal)0); QCOMPARE(line.width() + data->counterWidth() + data->counterSpacing(), (qreal)200); block = block.next(); } }
void tst_QTextFormat::testTabsUsed() { QTextDocument doc; QTextCursor cursor(&doc); QList<QTextOption::Tab> tabs; QTextBlockFormat format; QTextOption::Tab tab; tab.position = 100; tabs.append(tab); format.setTabPositions(tabs); cursor.mergeBlockFormat(format); cursor.insertText("foo\tbar"); //doc.setPageSize(QSizeF(200, 200)); doc.documentLayout()->pageCount(); // force layout; QTextBlock block = doc.begin(); QTextLayout *layout = block.layout(); QVERIFY(layout); QCOMPARE(layout->lineCount(), 1); QTextLine line = layout->lineAt(0); QCOMPARE(line.cursorToX(4), 100.); QTextOption option = layout->textOption(); QCOMPARE(option.tabs().count(), tabs.count()); }
void setUnicodeText(const QString &text, const QFont &font, const QColor &color) { deleteContent(); QRawFont raw_font = QRawFont::fromFont(font, QFontDatabase::Latin); qreal line_width = raw_font.averageCharWidth() * text.size(); QSGRenderContext *sgr = QQuickItemPrivate::get(m_owner)->sceneGraphRenderContext(); QTextLayout layout(text,font); layout.beginLayout(); QTextLine line = layout.createLine(); line.setLineWidth(line_width); //Q_ASSERT(!layout.createLine().isValid()); layout.endLayout(); QList<QGlyphRun> glyphRuns = line.glyphRuns(); qreal xpos = 0; for (int i = 0; i < glyphRuns.size(); i++) { QSGGlyphNode *node = sgr->sceneGraphContext()->createGlyphNode(sgr, false); node->setOwnerElement(m_owner); node->geometry()->setIndexDataPattern(QSGGeometry::StaticPattern); node->geometry()->setVertexDataPattern(QSGGeometry::StaticPattern); node->setGlyphs(QPointF(xpos, raw_font.ascent()), glyphRuns.at(i)); node->setStyle(QQuickText::Normal); node->setColor(color); xpos += raw_font.averageCharWidth() * glyphRuns.at(i).positions().size(); node->update(); appendChildNode(node); } }
void setContent(const ToolTipContent &data) { QString html; if (!data.mainText().isEmpty()) { html.append("<div><b>" + data.mainText() + "</b></div>"); } html.append(data.subText()); m_anchor.clear(); m_document->clear(); data.registerResources(m_document); if (!html.isEmpty()) { m_document->setHtml("<p>" + html + "</p>"); } m_document->adjustSize(); m_haloRects.clear(); QTextLayout *layout = m_document->begin().layout(); //layout->setPosition(QPointF(textRect.x(), textBoundingRect->y())); QTextLine line; for (int i = 0; i < layout->lineCount(); ++i) { line = layout->lineAt(i); // Add halo rect only when a non empty line is found if (line.naturalTextWidth()) { m_haloRects.append(line.naturalTextRect().translated(layout->position().toPoint()).toRect().translated(m_margin, m_margin)); } } update(); }
//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(); }
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())); }
void RowHeader::drawText(QPainter* painter, const QFont& font, qreal ypos, qreal width, const QString& text) const { register Sheet * const sheet = m_pCanvas->activeSheet(); if (!sheet) return; const double scaleX = POINT_TO_INCH(double(KoDpi::dpiX())); const double scaleY = POINT_TO_INCH(double(KoDpi::dpiY())); // Qt scales the font already with the logical resolution. Do not do it twice! painter->save(); painter->scale(1.0 / scaleX, 1.0 / scaleY); QTextLayout textLayout(text, font); textLayout.beginLayout(); textLayout.setTextOption(QTextOption(Qt::AlignHCenter)); forever { QTextLine line = textLayout.createLine(); if (!line.isValid()) break; line.setLineWidth(width * scaleX); } textLayout.endLayout(); QPointF loc(0, ypos * scaleY); textLayout.draw(painter, loc); painter->restore(); }
int Font::offsetForPositionForComplexText(const TextRun& run, int position, bool includePartialGlyphs) const { QString string = qstring(run); QTextLayout layout(string, font()); QTextLine line = setupLayout(&layout, run); return line.xToCursor(position); }
int JobItem::descriptionHeight(const QStyleOptionViewItem & option) { int textTotalWidth = 0; int lineWidth = option.rect.width() - 2 * m_itemPadding; QString description = m_job->description().simplified(); QTextLayout descriptionLayout(description, m_descriptionFont, m_paintDevice); descriptionLayout.beginLayout(); for (int i = 0; i < m_descriptionLineCount - 1; ++i) { QTextLine line = descriptionLayout.createLine(); if (!line.isValid()) { // There is no text left to be inserted into the layout. break; } line.setLineWidth(lineWidth); textTotalWidth += line.naturalTextWidth(); } descriptionLayout.endLayout(); // Add space for last visible line. textTotalWidth += lineWidth; m_descriptionText = m_descriptionFontMetrics.elidedText(description, Qt::ElideRight, textTotalWidth); m_descriptionRect = m_descriptionFontMetrics.boundingRect(0, 0, option.rect.width() - 2 * m_itemPadding, 0, descriptionFlags(), m_descriptionText); return m_descriptionRect.height(); }
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(); }
bool addLine(QTextLine &line) { if (line.height() > 20) m_y += line.height(); else m_y += 14.4; return false; }
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 KCRowHeader::drawText(QPainter& painter, const QFont& font, const QPointF& location, const QString& text) const { register KCSheet * const sheet = m_pView->activeSheet(); if (!sheet) return; const double scaleX = POINT_TO_INCH(double(KoDpi::dpiX())); const double scaleY = POINT_TO_INCH(double(KoDpi::dpiY())); // Qt scales the font already with the logical resolution. Do not do it twice! painter.save(); painter.scale(1.0 / scaleX, 1.0 / scaleY); QTextLayout textLayout(text, font); textLayout.beginLayout(); forever { QTextLine line = textLayout.createLine(); if (!line.isValid()) break; line.setLineWidth(width() * scaleX); } textLayout.endLayout(); QPointF loc(location.x() * scaleX, location.y() * scaleY); textLayout.draw(&painter, loc); painter.restore(); }
void GroupedLineEdit::paintEvent(QPaintEvent *e) { QTextLine line = document()->findBlock(0).layout()->lineAt(0); QPainter painter(viewport()); painter.setRenderHint(QPainter::Antialiasing, true); painter.fillRect(0, 0, viewport()->width(), viewport()->height(), palette().base()); QVectorIterator<QColor> i(d->colors); i.toFront(); foreach (const Private::Block &block, d->blocks) { qreal start_x = line.cursorToX(block.start, QTextLine::Leading); qreal end_x = line.cursorToX(block.end-1, QTextLine::Trailing); QPainterPath path; QRectF rectangle( start_x - 1.0 - double(horizontalScrollBar()->value()), 1.0, end_x - start_x + 2.0, double(viewport()->height() - 2)); if (!i.hasNext()) i.toFront(); path.addRoundedRect(rectangle, 5.0, 5.0); painter.setPen(i.peekNext()); if (palette().color(QPalette::Text).lightnessF() <= 0.3) painter.setBrush(i.next().lighter()); else if (palette().color(QPalette::Text).lightnessF() <= 0.6) painter.setBrush(i.next()); else painter.setBrush(i.next().darker()); painter.drawPath(path); } QPlainTextEdit::paintEvent(e); }
int Font::offsetForPositionForComplexText(const TextRun& run, int position, bool) const { const QString string = fixSpacing(qstring(run)); QTextLayout layout(string, font()); QTextLine line = setupLayout(&layout, run); return line.xToCursor(position); }
///Indique si on est à la dernière ligne bool RzxTextEdit::atEnd() const { QTextBlock block = textCursor().block(); if(block.next().isValid()) return false; QTextLine line = currentTextLine(); return line.isValid() && line.lineNumber() == block.layout()->lineCount() - 1; }
///Indique si on est à la première ligne bool RzxTextEdit::atBeginning() const { QTextBlock block = textCursor().block(); if(block.previous().isValid()) return false; QTextLine line = currentTextLine(); return line.isValid() && !line.lineNumber(); }
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(); }
int Font::offsetForPositionForComplexText(const TextRun& run, float position, bool) const { String sanitized = Font::normalizeSpaces(run.characters(), run.length()); QString string = fromRawDataWithoutRef(sanitized); QTextLayout layout(string, font()); QTextLine line = setupLayout(&layout, run); return line.xToCursor(position); }
void TestDocumentLayout::placeAnchoredFrame() { initForNewTest(QString()); MockShape *picture = new MockShape(); picture->setSize(QSizeF(100, 100)); KTextAnchor *anchor = new KTextAnchor(picture); anchor->setOffset(QPointF(23, 45)); QTextCursor cursor(doc); KInlineTextObjectManager *manager = new KInlineTextObjectManager(); layout->setInlineTextObjectManager(manager); MockLayoutState *state = new MockLayoutState(doc); layout->setLayout(state); state->shape = shape1; QCOMPARE(doc->begin().text().length(), 0); manager->insertInlineObject(cursor, anchor); QCOMPARE(doc->begin().text().length(), 1); QCOMPARE(cursor.position(), 1); shape1->setPosition(QPointF(300, 300)); layout->layout(); QCOMPARE(picture->parent(), shape1); QCOMPARE(picture->position(), QPointF(23, 59.4)); cursor.setPosition(0); cursor.insertText("foo"); // moves my anchors slightly to the right/down and gives line height layout->layout(); QCOMPARE(picture->parent(), shape1); QPointF newPos = picture->position(); QVERIFY(newPos.x() > 23); QVERIFY(newPos.y() > 45); // it adds the baseline now cursor.movePosition(QTextCursor::End); cursor.insertText("\nNew Line\nAnd another"); layout->layout(); QCOMPARE(picture->position(), newPos); QTextLayout *firstLineLayout = doc->begin().layout(); QTextOption option = firstLineLayout->textOption(); option.setAlignment(Qt::AlignHCenter); firstLineLayout->setTextOption(option); layout->layout(); QTextLine first = doc->begin().layout()->lineAt(0); QVERIFY(first.isValid()); QVERIFY(first.naturalTextRect().x() > 10); newPos.setX(newPos.x() + first.naturalTextRect().x()); // text is moved due to alignment QCOMPARE(picture->position(), newPos); anchor->setOffset(QPointF()); anchor->setAlignment(KTextAnchor::Left); anchor->setAlignment(KTextAnchor::TopOfParagraph); layout->layout(); // image is 100 wide, now centered in a parent of 200 so X = 50 QCOMPARE(picture->position(), QPointF(50, 0)); }
int cursorPosition() const { if (!m_currentBlock.isValid()) return 0; int answer = m_currentBlock.position(); if (m_currentBlock.layout()->lineCount()) { QTextLine tl = m_currentBlock.layout()->lineAt(m_currentBlock.layout()->lineCount() - 1); answer += tl.textStart() + tl.textLength(); } return answer; }
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(); }
qreal TextDocumentLayout::blockWidth(const QTextBlock &block) { QTextLayout *layout = block.layout(); if (!layout->lineCount()) return 0; // only for layouted blocks qreal blockWidth = 0; for (int i = 0; i < layout->lineCount(); ++i) { QTextLine line = layout->lineAt(i); blockWidth = qMax(line.naturalTextWidth() + 8, blockWidth); } return blockWidth; }
void tst_QComplexText::bidiCursor_PDF() { QString str = QString::fromUtf8("\342\200\252hello\342\200\254"); QTextLayout layout(str); layout.beginLayout(); QTextLine line = layout.createLine(); layout.endLayout(); int size = str.size(); QVERIFY(line.cursorToX(size) == line.cursorToX(size - 1)); }
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(); }
FloatRect Font::selectionRectForComplexText(const TextRun& run, const IntPoint& pt, int h, int from, int to) const { const QString string = fixSpacing(qstring(run)); QTextLayout layout(string, font()); QTextLine line = setupLayout(&layout, run); float x1 = line.cursorToX(from); float x2 = line.cursorToX(to); if (x2 < x1) qSwap(x1, x2); return FloatRect(pt.x() + x1, pt.y(), x2 - x1, h); }
int StyledLabel::posToCursor(const QPointF &pos) { if (pos.y() < 0 || pos.y() > height()) return -1; for (int l = _layout.lineCount() - 1; l >= 0; l--) { QTextLine line = _layout.lineAt(l); if (pos.y() >= line.y()) { return line.xToCursor(pos.x(), QTextLine::CursorOnCharacter); } } return -1; }