예제 #1
0
void KPrAttributeHeight::initCache(KPrAnimationCache *animationCache, int step, KPrShapeAnimation * shapeAnimation, qreal startValue, qreal endValue)
{
    qreal v1 = 0.0, v2 = 0.0, tx = 0.0, ty = 0.0;
    KoShape * shape = shapeAnimation->shape();
    KoTextBlockData * textBlockData = shapeAnimation->textBlockData();

    if (textBlockData) {
        if (KoTextShapeData *textShapeData = dynamic_cast<KoTextShapeData*>(shape->userData())) {
            QTextDocument *textDocument = textShapeData->document();
            for (int i = 0; i < textDocument->blockCount(); i++) {
                QTextBlock textBlock = textDocument->findBlockByNumber(i);
                if (textBlock.userData() == textBlockData) {
                    QTextLayout *layout = textBlock.layout();
                    v1 = startValue * animationCache->pageSize().height() / layout->boundingRect().height();
                    v2 = endValue * animationCache->pageSize().height() / layout->boundingRect().height();
                    tx = layout->minimumWidth() * animationCache->zoom() / 2;
                    ty = layout->boundingRect().height() * animationCache->zoom() / 2;
                }
            }
        }
    }
    else {
        v1 = startValue * animationCache->pageSize().height() / shape->size().height();
        v2 = endValue * animationCache->pageSize().height() / shape->size().height();
        tx = shape->size().width() * animationCache->zoom() / 2;
        ty = shape->size().height() * animationCache->zoom() / 2;
    }
    animationCache->init(step, shape, textBlockData, "transform", QTransform().translate(tx, ty).scale(1, v1).translate(-tx, -ty));
    animationCache->init(step + 1, shape, textBlockData, "transform", QTransform().translate(tx, ty).scale(1, v2).translate(-tx, -ty));
}
예제 #2
0
void KPrAttributeHeight::updateCache(KPrAnimationCache *cache, KPrShapeAnimation *shapeAnimation, qreal value)
{
    qreal tx = 0.0, ty = 0.0;
    KoShape * shape = shapeAnimation->shape();
    KoTextBlockData * textBlockData = shapeAnimation->textBlockData();
    QTransform transform;
    if (textBlockData) {
        if (KoTextShapeData *textShapeData = dynamic_cast<KoTextShapeData*>(shape->userData())) {
            QTextDocument *textDocument = textShapeData->document();
            for (int i = 0; i < textDocument->blockCount(); i++) {
                QTextBlock textBlock = textDocument->findBlockByNumber(i);
                if (textBlock.userData() == textBlockData) {
                    QTextLayout *layout = textBlock.layout();
                    value = value * cache->pageSize().height() / layout->boundingRect().height();
                    tx = layout->minimumWidth() * cache->zoom() / 2;
                    ty = layout->boundingRect().height() * cache->zoom() / 2;
                }
            }
        }
    }
    else {
        value = value * cache->pageSize().height() / shape->size().height();
        tx = shape->size().width() * cache->zoom() / 2;
        ty = shape->size().height() * cache->zoom() / 2;
    }
    transform.translate(tx, ty).scale(1, value).translate(-tx, -ty);
    cache->update(shape, shapeAnimation->textBlockData(), "transform", transform);
}
예제 #3
0
void DevLineNumber::paintEvent(QPaintEvent *e)
{
	const QPixmap pm[] ={ 	
							QPixmap(":/break.png"),
							QPixmap(":/error.png")
						};
	
	int n = 1, contentsY = editor->verticalScrollBar()->value();
	qreal pageBottom = contentsY + editor->viewport()->height();
	const QFontMetrics fm( editor->document()->defaultFont() );
	
	QPainter p(this);
	
	for (QTextBlock block = editor->document()->begin();
		block.isValid(); 
		block = block.next(), ++n )
	{
		QTextLayout *layout = block.layout();
		
		const QRectF boundingRect = layout->boundingRect();
		QPointF position = layout->position();
		if (position.y() + boundingRect.height() < contentsY)
			continue;
		if (position.y() > pageBottom)
			break;
			
		int posY = qRound(position.y());
            
		BlockData *dat = BlockData::data(block);
		const QString txt = QString::number(n);
		
		p.drawText(	0,
					posY - contentsY,
					width(),
					fm.lineSpacing(),
					Qt::AlignRight | Qt::AlignVCenter,
					txt);
		
		if ( !dat )
			continue;
		
		int x = 0;
		
		if ( dat->s & BlockData::BreakPoint )
		p.drawPixmap(	15*(x++),
						posY - contentsY +(fm.lineSpacing() - (*pm).height())/2,
						(*pm).width(),
						(*pm).height(),
						*pm);
		
		if ( dat->s & BlockData::Error )
		p.drawPixmap(	15*(x++),
						posY - contentsY +(fm.lineSpacing() - pm[1].height())/2,
						pm[1].width(),
						pm[1].height(),
						pm[1]);
	}
}
예제 #4
0
int KTextDocumentLayout::hitTestIterated(QTextFrame::iterator begin, QTextFrame::iterator end, const QPointF &point, Qt::HitTestAccuracy accuracy) const
{
    int position = -1;
    QTextFrame::iterator it = begin;
    for (it = begin; it != end; ++it) {
        QTextBlock block = it.currentBlock();
        QTextTable *table = qobject_cast<QTextTable*>(it.currentFrame());
        QTextFrame *subFrame = it.currentFrame();

        if (table) {
            QTextTableCell cell = m_state->hitTestTable(table, point);
            if (cell.isValid()) {
                position = hitTestIterated(cell.begin(), cell.end(), point,
                                accuracy);
                if (position == -1)
                    position = cell.lastPosition();
                return position;
            }
            continue;
        } else if (subFrame) {
            position = hitTestIterated(subFrame->begin(), subFrame->end(), point, accuracy);
            if (position != -1)
                return position;
            continue;
        } else {
            if (!block.isValid())
                continue;
        }
        // kDebug(32500) <<"hitTest[" << point.x() <<"," << point.y() <<"]";
        QTextLayout *layout = block.layout();
        if (point.y() > layout->boundingRect().bottom()) {
            // just skip this block. position = block.position() + block.length() - 1;
            continue;
        }
        for (int i = 0; i < layout->lineCount(); i++) {
            QTextLine line = layout->lineAt(i);
            // kDebug(32500) <<" + line[" << line.textStart() <<"]:" << line.y() <<"-" << line.height();
            if (point.y() > line.y() + line.height()) {
                position = line.textStart() + line.textLength();
                continue;
            }
            if (accuracy == Qt::ExactHit && point.y() < line.y()) // between lines
                return -1;
            if (accuracy == Qt::ExactHit && // left or right of line
                    (point.x() < line.x() || point.x() > line.x() + line.width()))
                return -1;
            if (point.x() > line.width() && layout->textOption().textDirection() == Qt::RightToLeft) {
                // totally right of RTL text means the position is the start of the text.
                return block.position() + line.textStart();
            }
            return block.position() + line.xToCursor(point.x());
        }
    }
    return -1;
}
예제 #5
0
bool XMLTextEdit::event( QEvent *event ) 
{
  if (event->type()==QEvent::Paint) {
    QPainter p(this);
    p.fillRect(0, 0, 50, height(), QColor("#636363"));
		QFont workfont(font());
    QPen pen(QColor("#ffffff"),1);
		p.setPen(pen); 
		p.setFont (workfont);
    int contentsY = verticalScrollBar()->value();
    qreal pageBottom = contentsY+viewport()->height();
    int m_lineNumber(1);
    const QFontMetrics fm=fontMetrics();
    const int ascent = fontMetrics().ascent() +1;
      
    for (QTextBlock block=document()->begin(); block.isValid(); block=block.next(), m_lineNumber++) {
      QTextLayout *layout = block.layout();
      const QRectF boundingRect = layout->boundingRect();
      QPointF position = layout->position();
      if ( position.y() +boundingRect.height() < contentsY ) {
        continue;
      }
      if ( position.y() > pageBottom ) {
        break;
      }
      const QString txt = QString::number(m_lineNumber);
      p.drawText(50-fm.width(txt)-2, qRound(position.y())-contentsY+ascent, txt);
			
      }
			p.setPen(QPen(Qt::NoPen)); 
    } else if ( event->type() == QEvent::KeyPress ) {
			QKeyEvent *ke = static_cast<QKeyEvent *>(event);
			if ((ke->modifiers() & Qt::ControlModifier) && ke->key() == Qt::Key_Minus)   {
				QTextEdit::zoomOut();
				return true;
			}
			if ((ke->modifiers() & Qt::ControlModifier) && ke->key() == Qt::Key_Plus)   {
				QTextEdit::zoomIn();
				return true;
			}
		}
    return QTextEdit::event(event);
} 
예제 #6
0
QRectF TextDocumentLayout::blockBoundingRect(const QTextBlock &block) const
{
    if (!block.isValid()) { return QRectF(); }
    QTextLayout *tl = block.layout();

    if (!tl->lineCount())
        const_cast<TextDocumentLayout*>(this)->layoutBlock(block);


    QRectF br;
    if (block.isVisible()) {
        br = QRectF(QPointF(0, 0), tl->boundingRect().bottomRight());
        if (tl->lineCount() == 1)
            br.setWidth(qMax(br.width(), tl->lineAt(0).naturalTextWidth()));
        qreal margin = document()->documentMargin();
        br.adjust(0, 0, margin, 0);
        if (!block.next().isValid())
            br.adjust(0, 0, 0, margin);
    }
    return br;
}
예제 #7
0
void LineNumbers::paintEvent( QPaintEvent* )
{
	int contentsY = m_textEdit->verticalScrollBar()->value();
	qreal pageBottom = contentsY + m_textEdit->viewport()->height();
	int m_lineNumber = 1;
	const QFontMetrics fm = fontMetrics();
        const int ascent = fontMetrics().ascent() +1;
        QPainter p( this );
	for ( QTextBlock block = m_textEdit->document()->begin(); block.isValid(); block = block.next(), m_lineNumber++ )
	{
		QTextLayout* layout = block.layout();
		const QRectF boundingRect = layout->boundingRect();
		QPointF position = layout->position();
		if ( position.y() +boundingRect.height() < contentsY )
			continue;
		if ( position.y() > pageBottom )
			break;
		const QString txt = QString::number( m_lineNumber );
		if( m_lineNumber == m_executedLine )
		{
			int centreV = qRound( position.y() ) -contentsY + 8;
			p.setBrush( Qt::blue );
			float x = width()-1;
			const QPointF points[7] = {
        			QPointF(x, centreV),
        			QPointF(x-9, centreV-8),
        			QPointF(x-9, centreV-4),
        			QPointF(x-15, centreV-4),
        			QPointF(x-15, centreV+4),
        			QPointF(x-9, centreV+4),
        			QPointF(x-9, centreV+8),
    			};

    			p.drawPolygon(points, 7);
		}
		else
                        p.drawText( width() -fm.width( txt ) - 2, qRound( position.y() ) -contentsY +ascent, txt );
        }
	p.end();
}
예제 #8
0
void LineNumberWidget::paintEvent(QPaintEvent *){
	int contentsY = editor->verticalScrollBar()->value();
	qreal pageBottom = contentsY + editor->viewport()->height();
	int lineNumber = 1;
	const QFontMetrics fm = fontMetrics();
	const int ascent = fontMetrics().ascent() + 1; // height = ascent + descent + 1

	QPainter p(this);

	for (QTextBlock block = editor->document()->begin();block.isValid();block = block.next(), ++lineNumber) {
		QTextLayout *layout = block.layout();

		const QRectF boundingRect = layout->boundingRect();
		QPointF position = layout->position();
		if (position.y() + boundingRect.height() < contentsY)
			continue;
		if (position.y() > pageBottom)
			break;

		const QString txt = QString::number(lineNumber);
		p.drawText(width() - fm.width(txt), qRound(position.y()) - contentsY + ascent, txt);
		}
	}
예제 #9
0
void TextLineNumbers::paintEvent( QPaintEvent* )
{
	int contentsY = m_textEdit->verticalScrollBar()->value();
	qreal pageBottom = contentsY + m_textEdit->viewport()->height();
	int m_lineNumber = 1;
	const QFontMetrics fm = fontMetrics();
	const int ascent = fontMetrics().ascent() +1;
	
	QPainter p( this );
	for ( QTextBlock block = m_textEdit->document()->begin(); block.isValid(); block = block.next(), m_lineNumber++ )
	{
		QTextLayout* layout = block.layout();
		const QRectF boundingRect = layout->boundingRect();
		QPointF position = layout->position();
		if ( position.y() +boundingRect.height() < contentsY )
			continue;
		if ( position.y() > pageBottom )
			break;
		const QString txt = QString::number( m_lineNumber - 1 );
		
		p.drawText( width() -fm.width( txt ) - 2, qRound( position.y() ) -contentsY +ascent, txt ); // -fm.width( "0" ) is an ampty place/indent 		
	}
	p.end();
}
예제 #10
0
파일: qstatictext.cpp 프로젝트: maxxant/qt
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();
    }
}
예제 #11
0
void ScCodeEditor::blinkCode( const QTextCursor & c )
{
    if( !c.document() || !c.hasSelection() ) return;

    Settings::Manager *settings = Main::settings();
    QTextCharFormat evalCodeTextFormat = settings->getThemeVal("evaluatedCode");

    QTextDocument *doc = c.document();

    int startPos = c.selectionStart();
    int endPos = c.selectionEnd();
    QTextBlock startBlock = doc->findBlock(startPos);
    QTextBlock endBlock = doc->findBlock(endPos);
    startPos -= startBlock.position();
    endPos -= endBlock.position();

    // Get the bounds of visible blocks within the cursor's selection:

    QTextBlock block = firstVisibleBlock();
    int idx = block.blockNumber();
    int sidx = startBlock.blockNumber();

    QTextBlock firstBlock, lastBlock;
    firstBlock = lastBlock = block;

    QRectF geom = blockBoundingGeometry(block).translated(contentOffset());
    qreal top = geom.top();
    qreal bottom = top;
    qreal width=0;

    while(block.isValid() && bottom < viewport()->rect().height())
    {
        if(block.isVisible())
        {
            QTextLayout *l = block.layout();
            QRectF r = l->boundingRect();
            bottom += r.height();
            if(idx < sidx) {
                // Block not within the selection. Will skip it.
                top = bottom;
            }
            else {
                // Block within the selection.
                width = qMax(width, l->maximumWidth() + r.left());
            }
        }

        if(block == endBlock) break;

        block = block.next();
        ++idx;
        if(top == bottom)
            firstBlock = block;
    }

    lastBlock = block;

    if(bottom == top) {
        //qDebug("no visible block.");
        return;
    }

    // Construct a pixmap to render the code on:

    QPixmap pix( QSize(qCeil(width), qCeil(bottom - top)) );
    pix.fill(QColor(0,0,0,0));

    // Render the visible blocks:

    QPainter painter(&pix);
    QVector<QTextLayout::FormatRange> selections;
    block = firstBlock;
    int y=0;
    while( block.isValid() )
    {
        if (block.isVisible())
        {
            QRectF blockRect = block.layout()->boundingRect();

            // Use extra char formatting to hide code outside of selection
            // and modify the appearance of selected code:

            QTextLayout::FormatRange range;
            selections.clear();

            int start = 0;
            if(block == startBlock) {
                range.start = 0;
                range.length = startPos;
                range.format.setForeground(QColor(0,0,0,0));
                range.format.setBackground(Qt::NoBrush);
                selections.append(range);
                start = startPos;
            }

            range.start = start;
            range.length = (block == endBlock ? endPos : block.length() - 1) - range.start;
            range.format = evalCodeTextFormat;
            selections.append(range);

            if(block == endBlock) {
                range.start = range.start + range.length;
                range.length = block.length() - 1 - range.start;
                range.format.setForeground(QColor(0,0,0,0));
                range.format.setBackground(Qt::NoBrush);
                selections.append(range);
            }

            block.layout()->draw(&painter, QPointF(0,y), selections);

            y += blockRect.height();
        }

        if(block == lastBlock) break;

        block = block.next();
    }

    // Create an overlay item to display the pixmap, and animate it:

    CodeFragmentOverlay *item = new CodeFragmentOverlay();
    item->setPixmap(pix);
    item->setPos(geom.left(), top);

    mOverlay->addItem(item);

    QPropertyAnimation *anim = new QPropertyAnimation(item, "opacity", item);
    anim->setDuration(mBlinkDuration);
    anim->setStartValue(1.0);
    anim->setEndValue(0.0);
    anim->setEasingCurve( QEasingCurve::InCubic );
    anim->start();

    connect(anim, SIGNAL(finished()), item, SLOT(deleteLater()));
}