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); document.drawContents(p); p->restore(); if (textWidth >= 0.0) document.adjustSize(); // Find optimal size actualSize = document.size(); } }
void ProjectorWindow::paintEvent(QPaintEvent* ev) { // This event is called when the widget is asked to repaint itself // All of our custom painter logic should go in here. // Painter to paint the window QPainter painter; // Hold on to the normal (transparent) brush QBrush normalBrush; // List of data HTMLs QStringList dataHtml; // Pens (i.e. line drawing settings for the painter) QPen ballPen = QPen((QColor(0, 0, 255))); ballPen.setWidthF(mPointThickness); QPen kfSeenPen = QPen((QColor(255,0,0))); kfSeenPen.setWidthF(mPointThickness); QPen kfMissPen = QPen((QColor(255,255,0))); kfMissPen.setWidthF(mPointThickness); QPen markPen = QPen((QColor(255,255,255))); markPen.setWidthF(mPointThickness); QPen fitPen = QPen((QColor(255,0,255))); fitPen.setWidthF(mFitThickness); QPen fitLockPen = QPen(mColorFitLock); fitLockPen.setWidthF(mFitThickness); // We have to begin painting. Remember to end. painter.begin(this); normalBrush = painter.brush(); // This brush is the background color of the widget. // Fill the window in case. QBrush background = QBrush(QColor(0,0,0)); painter.fillRect(ev->rect(), background); // Draw the ball indicators on the projector screen painter.setPen(ballPen); QList<TrackingBall>::const_iterator ballsIter; for (ballsIter = mBalls.begin(); ballsIter != mBalls.end(); ++ballsIter) { painter.drawEllipse( (QPoint)(*ballsIter).center()*2, (int)(*ballsIter).r()*2, (int)(*ballsIter).r()*2); } // Draw the KF prediction indicators on the screen QList<KFPrediction>::const_iterator predsIter; for (predsIter = mPreds.begin(); predsIter != mPreds.end(); ++predsIter) { // The color of the indicator depends on if the ball was actually // seen on this frame or not if (((*predsIter).seen() || !mColorMiss)) { painter.setPen(kfSeenPen); } else { painter.setPen(kfMissPen); } // Draw the bounding box of the predicted ball if (mVerboseKF) { painter.drawRect(relRectToWindow((*predsIter).bbox())); } else { painter.drawEllipse(QRectF(relPointToWindow( (*predsIter).bbox().center()) - QPointF(mPointRadius/2,mPointRadius/2), QSizeF(mPointRadius,mPointRadius))); } if (mShowJet) { // Draw the predicted velocities of the predicted ball painter.drawLine(relPointToWindow((*predsIter).bbox().center()), relPointToWindow( (*predsIter).bbox().center() + ((QPointF)(*predsIter).jet() * (*predsIter).dt()))); } } int j; double t0; j = 0; // Draw the predicted flight trajectory of the ball if (mShowParam || mShowFit) { double a, b, A, B, C, U, V, W; // x(t) = at + b a = mFitLineX[1]; b = mFitLineX[0]; // y(t) = At^2 + Bt + C A = mFitParabolaY[2]; B = mFitParabolaY[1]; C = mFitParabolaY[0]; // y(x) = Ux^2 + Vx + W U = A/a/a; V = B/a - 2*A*b/a/a; W = A*b*b/a/a - B*b/a + C; // Show the fit parabola if (mShowParabola) { if (mFitLocked) { painter.setPen(fitLockPen); } else { painter.setPen(fitPen); } QPointF p1(0, W); QPointF p2(mProjSize.width(), U*mProjSize.width()*mProjSize.width() + V*mProjSize.width() + W); QPointF c(0.5*mProjSize.width(), W + .5*mProjSize.width()*V); QPainterPath fitPath(relPointToWindow(p1)); fitPath.quadTo(relPointToWindow(c), relPointToWindow(p2)); painter.drawPath(fitPath); } // Draw the predicted y(t) and x(t) equation if (mShowParam) { dataHtml << QString("y(t) = %1 t<sup>2</sup> + %2 t + %3") .arg(A, 0, 'f', 3) .arg(B, 0, 'f', 3) .arg(C, 0, 'f', 3) << QString("x(t) = %1 t + %2") .arg(a, 0, 'f', 3) .arg(b, 0, 'f', 3); } } if (!mMarkedPoints.empty()) { t0 = mMarkedPoints.at(0).t(); } //QStringList markHtml; QRectF markRect; QFont markFont = painter.font(); markFont.setPointSize(mFontSize); int mMarkRadius = mPointRadius*0.8; // Draw marked points painter.setFont(markFont); for (predsIter = mMarkedPoints.begin(); predsIter != mMarkedPoints.end(); ++predsIter) { painter.setPen(markPen); dataHtml << QString("%1: (%2, %3, %4)") .arg(j) .arg(predsIter->t()-t0, 0, 'f', 3) .arg(predsIter->bbox().center().x(), 0, 'f', 3) .arg(predsIter->bbox().center().y(), 0, 'f', 3); markRect = QRectF((relPointToWindow( (*predsIter).bbox().center()) - QPointF(mMarkRadius/2,mMarkRadius/2)), QSizeF(mMarkRadius,mMarkRadius)); painter.setBrush(background); painter.drawEllipse(markRect); painter.setBrush(normalBrush); painter.drawText(markRect, Qt::AlignCenter|Qt::TextDontClip, QString("%1").arg(j)); j++; } if (!dataHtml.empty()) { QTextDocument td; td.setDefaultStyleSheet( QString("body {" " color: rgb(255,255,255);" " font-size: %1pt;" "}") .arg(mFontSize)); td.setHtml(QString( "<body>%1</body>") .arg(dataHtml.join("<br>")) ); td.drawContents(&painter); } painter.end(); }