void GridItem::draw( QPainter *painter, const QwtScaleMap &xMap, const QwtScaleMap &yMap, const QRectF &canvasRect ) const { const bool doAlign = QwtPainter::roundingAlignment( painter ); const QRectF area = QwtScaleMap::invTransform( xMap, yMap, canvasRect ); QList<double> xValues; if ( m_orientations & Qt::Horizontal ) { xValues = m_xScaleDiv.ticks( QwtScaleDiv::MajorTick ); if ( m_isXMinEnabled ) { xValues += m_xScaleDiv.ticks( QwtScaleDiv::MediumTick ); xValues += m_xScaleDiv.ticks( QwtScaleDiv::MinorTick ); } if ( m_gridAttributes & FillCanvas ) { xValues += area.left(); xValues += area.right(); } qSort( xValues ); } QList<double> yValues; if ( m_orientations & Qt::Vertical ) { yValues = m_yScaleDiv.ticks( QwtScaleDiv::MajorTick ); if ( m_isYMinEnabled ) { yValues += m_yScaleDiv.ticks( QwtScaleDiv::MediumTick ); yValues += m_yScaleDiv.ticks( QwtScaleDiv::MinorTick ); } if ( m_gridAttributes & FillCanvas ) { yValues += area.top(); yValues += area.bottom(); } qSort( yValues ); } painter->setPen( Qt::NoPen ); if ( ( m_orientations & Qt::Horizontal ) && ( m_orientations & Qt::Vertical ) ) { for ( int i = 1; i < xValues.size(); i++ ) { double x1 = xMap.transform( xValues[i - 1] ); double x2 = xMap.transform( xValues[i] ); if ( doAlign ) { x1 = qRound( x1 ); x2 = qRound( x2 ); } for ( int j = 1; j < yValues.size(); j++ ) { const QRectF rect( xValues[i - 1], yValues[j - 1], xValues[i] - xValues[i - 1], yValues[j] - yValues[j - 1] ); painter->setBrush( brush( i - 1, j - 1, rect ) ); double y1 = yMap.transform( yValues[j - 1] ); double y2 = yMap.transform( yValues[j] ); if ( doAlign ) { y1 = qRound( y1 ); y2 = qRound( y2 ); } QwtPainter::drawRect( painter, x1, y1, x2 - x1, y2 - y1 ); } } } else if ( m_orientations & Qt::Horizontal ) { for ( int i = 1; i < xValues.size(); i++ ) { const QRectF rect( xValues[i - 1], area.top(), xValues[i] - xValues[i - 1], area.bottom() ); painter->setBrush( brush( i - 1, 0, rect ) ); double x1 = xMap.transform( xValues[i - 1] ); double x2 = xMap.transform( xValues[i] ); if ( doAlign ) { x1 = qRound( x1 ); x2 = qRound( x2 ); } QwtPainter::drawRect( painter, x1, canvasRect.top(), x2 - x1, canvasRect.height() ); } } else if ( m_orientations & Qt::Vertical ) { for ( int i = 1; i < yValues.size(); i++ ) { const QRectF rect( area.left(), yValues[i - 1], area.width(), yValues[i] - yValues[i - 1] ); painter->setBrush( brush( 0, i - 1, rect ) ); double y1 = yMap.transform( yValues[i - 1] ); double y2 = yMap.transform( yValues[i] ); if ( doAlign ) { y1 = qRound( y1 ); y2 = qRound( y2 ); } QwtPainter::drawRect( painter, canvasRect.left(), y1, canvasRect.width(), y2 - y1 ); } } }
void QEglFSCursor::draw(const QRectF &r) { if (!m_program) { // one time initialization createShaderPrograms(); if (!m_cursorAtlas.texture) { createCursorTexture(&m_cursorAtlas.texture, m_cursorAtlas.image); m_cursorAtlas.image = QImage(); if (m_cursor.shape != Qt::BitmapCursor) m_cursor.texture = m_cursorAtlas.texture; } } if (m_cursor.shape == Qt::BitmapCursor && !m_cursor.customCursorImage.isNull()) { // upload the custom cursor createCursorTexture(&m_cursor.customCursorTexture, m_cursor.customCursorImage); m_cursor.texture = m_cursor.customCursorTexture; m_cursor.customCursorImage = QImage(); } Q_ASSERT(m_cursor.texture); glUseProgram(m_program); const GLfloat x1 = r.left(); const GLfloat x2 = r.right(); const GLfloat y1 = r.top(); const GLfloat y2 = r.bottom(); const GLfloat cursorCoordinates[] = { x1, y2, x2, y2, x1, y1, x2, y1 }; const GLfloat s1 = m_cursor.textureRect.left(); const GLfloat s2 = m_cursor.textureRect.right(); const GLfloat t1 = m_cursor.textureRect.top(); const GLfloat t2 = m_cursor.textureRect.bottom(); const GLfloat textureCoordinates[] = { s1, t2, s2, t2, s1, t1, s2, t1 }; glBindTexture(GL_TEXTURE_2D, m_cursor.texture); glEnableVertexAttribArray(m_vertexCoordEntry); glEnableVertexAttribArray(m_textureCoordEntry); glVertexAttribPointer(m_vertexCoordEntry, 2, GL_FLOAT, GL_FALSE, 0, cursorCoordinates); glVertexAttribPointer(m_textureCoordEntry, 2, GL_FLOAT, GL_FALSE, 0, textureCoordinates); glUniform1f(m_textureEntry, 0); glEnable(GL_BLEND); glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA); glDisable(GL_DEPTH_TEST); // disable depth testing to make sure cursor is always on top glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); glDisable(GL_BLEND); glBindTexture(GL_TEXTURE_2D, 0); glDisableVertexAttribArray(m_vertexCoordEntry); glDisableVertexAttribArray(m_textureCoordEntry); glUseProgram(0); }
bool OsmImport::parseDoc(QDomDocument &doc) { QDomNodeList list = doc.elementsByTagName("node"); for (int i = 0; i < list.count(); i++) { nodes.append(new osmNode(list.at(i).toElement())); } list = doc.elementsByTagName("way"); for (int i = 0; i < list.count(); i++) { ways.append(new osmWay(list.at(i).toElement(), nodes)); } bool doPrimary = ImportSettings::instance()->importPrimary(); bool doSecondary = ImportSettings::instance()->importSecondary(); bool doTertiary = ImportSettings::instance()->importTertiary(); bool doMotorway = ImportSettings::instance()->importMotorway(); bool doService = ImportSettings::instance()->importService(); bool doPath = ImportSettings::instance()->importPath(); bool doSteps = ImportSettings::instance()->importSteps(); bool doTrack = ImportSettings::instance()->importTrack(); bool doFootpath = ImportSettings::instance()->importFootway(); bool doResidential = ImportSettings::instance()->importResidential(); bool doLiving_street = ImportSettings::instance()->importLiving_street(); bool doCycleway = ImportSettings::instance()->importCycleway(); bool doTurning_circle = ImportSettings::instance()->importTurning_circle(); bool doPedestrian = ImportSettings::instance()->importPedestrian(); bool doUnclassified = ImportSettings::instance()->importUnclassified(); for (int i = 0; i < ways.count(); i++) { osmWay *w = ways.at(i); osmWay::wayType t = w->type; if ((t == osmWay::primary && doPrimary) || (t == osmWay::secondary && doSecondary) || (t == osmWay::tertiary && doTertiary) || (t == osmWay::motorway && doMotorway) || (t == osmWay::service && doService) || (t == osmWay::path && doPath) || (t == osmWay::steps && doSteps) || (t == osmWay::track && doTrack) || (t == osmWay::footway && doFootpath) || (t == osmWay::residential && doResidential) || (t == osmWay::living_street && doLiving_street) || (t == osmWay::cycleway && doCycleway) || (t == osmWay::turning_circle && doTurning_circle) || (t == osmWay::pedestrian && doPedestrian) || (t == osmWay::unclassified && doUnclassified)) { project->XVector = w->XVector; project->YVector = w->YVector; project->ZVector = w->ZVector; if (project->XVector.size() > 0) { project->addLineStrip(w->name,w->maxSpeed,w->bridge,w->numLanes,w->type); } } } qDeleteAll(ways.begin(), ways.end()); qDeleteAll(nodes.begin(), nodes.end()); ways.clear(); nodes.clear(); // resize BoundingBoxVisitor *visitor = new BoundingBoxVisitor(); project->getProjectData()->getRoadSystem()->accept(visitor); project->getProjectData()->getScenerySystem()->accept(visitor); QRectF box = visitor->getBoundingBox(); SetProjectDimensionsCommand *command = new SetProjectDimensionsCommand(project->getProjectData(), box.bottom() + 0.1 * box.height(), box.top() - 0.1 * box.height(), box.right() + 0.1 * box.width(), box.left() - 0.1 * box.width()); project->getProjectSettings()->executeCommand(command); return true; }
void CMapRaster::draw() { if(!dataset) return; pixBuffer.fill(Qt::white); QPainter _p_(&pixBuffer); QRectF viewport(x, y, size.width() * zoomfactor, size.height() * zoomfactor); QRectF intersect = viewport.intersected(maparea); // x/y offset [pixel] into file matrix qint32 xoff = intersect.left(); qint32 yoff = intersect.top(); // number of x/y pixel to read qint32 pxx = intersect.width(); qint32 pxy = intersect.height(); // the final image width and height in pixel qint32 w = (qint32)(pxx / zoomfactor) & 0xFFFFFFFC; qint32 h = (qint32)(pxy / zoomfactor); if((w*h) == 0) { return; } CPLErr err = CE_Failure; if(rasterBandCount == 1) { GDALRasterBand * pBand; pBand = dataset->GetRasterBand(1); QImage img(QSize(w,h),QImage::Format_Indexed8); img.setColorTable(colortable); err = pBand->RasterIO(GF_Read,(int)xoff,(int)yoff,pxx,pxy,img.bits(),w,h,GDT_Byte,0,0); if(!err) { double xx = (intersect.left() - x) / zoomfactor, yy = (intersect.top() - y) / zoomfactor; _p_.drawPixmap(xx,yy,QPixmap::fromImage(img)); } } else { QImage img(w,h, QImage::Format_ARGB32); QVector<quint8> buffer(w*h); img.fill(qRgba(255,255,255,255)); QRgb testPix = qRgba(GCI_RedBand, GCI_GreenBand, GCI_BlueBand, GCI_AlphaBand); for(int b = 1; b <= rasterBandCount; ++b) { GDALRasterBand * pBand; pBand = dataset->GetRasterBand(b); err = pBand->RasterIO(GF_Read, (int)xoff, (int)yoff, pxx, pxy, buffer.data(), w, h, GDT_Byte, 0, 0); if(!err) { int pbandColour = pBand->GetColorInterpretation(); unsigned int offset; for (offset = 0; offset < sizeof(testPix) && *(((quint8 *)&testPix) + offset) != pbandColour; offset++); if(offset < sizeof(testPix)) { quint8 * pTar = img.bits() + offset; quint8 * pSrc = buffer.data(); const int size = buffer.size(); for(int i = 0; i < size; ++i) { *pTar = *pSrc; pTar += sizeof(testPix); pSrc += 1; } } } } if(!err) { double xx = (intersect.left() - x) / zoomfactor, yy = (intersect.top() - y) / zoomfactor; _p_.drawPixmap(xx,yy,QPixmap::fromImage(img)); } } }
void MosaicAreaTool::userChangedBox() { bool latValid = false; bool lonValid = false; bool areaValid = false; if(!m_latLineEdit || !m_lonLineEdit || !m_areaLineEdit) { clearBox(); return; } QString latitude = m_latLineEdit->text(); if(latitude != "Null" && latitude != "") { int cursorPos = 0; QValidator::State validLat = m_latLineEdit->validator()->validate(latitude, cursorPos); if(validLat != QValidator::Acceptable) { QMessageBox::warning(getWidget(), "Error", "Latitude value must be in the range -90 to 90", QMessageBox::Ok, QMessageBox::NoButton, QMessageBox::NoButton); } else { latValid = true; } } //Validate longitude value QString longitude = m_lonLineEdit->text(); if(longitude != "Null" && longitude != "" && latValid) { int cursorPos = 0; QValidator::State validLon = m_lonLineEdit->validator()->validate(longitude, cursorPos); if(validLon != QValidator::Acceptable) { QMessageBox::warning(getWidget(), "Error", "Longitude value invalid", QMessageBox::Ok, QMessageBox::NoButton, QMessageBox::NoButton); } else { lonValid = true; } } QString areaString = m_areaLineEdit->text(); if(areaString != "Null" && areaString != "" && latValid && lonValid) { int cursorPos = 0; QValidator::State validArea = m_areaLineEdit->validator()->validate(areaString, cursorPos); if(validArea != QValidator::Acceptable) { QMessageBox::warning(getWidget(), "Error", "Area value invalid", QMessageBox::Ok, QMessageBox::NoButton, QMessageBox::NoButton); } else { areaValid = true; } } if(latValid && lonValid && areaValid) { double lat = IString(latitude.toStdString()).ToDouble(); double lon = IString(longitude.toStdString()).ToDouble(); double area = IString(areaString.toStdString()).ToDouble(); Projection *projection = getWidget()->getProjection(); Projection::ProjectionType ptype = projection->projectionType(); if (projection && ptype == Projection::Triaxial) { TProjection * tproj = (TProjection *) projection; if (tproj->SetGround(lat, lon)) { QPointF scenePos(projection->XCoord(), -1 * projection->YCoord()); QRectF sceneRect(getWidget()->getView()->sceneRect()); if(sceneRect.contains(scenePos)) { if(m_box != NULL) { clearBox(); } Distance distance(area, Distance::Meters); QPolygonF boxPoly; QRectF latLonRange = calcLatLonRange(QPointF(lon, lat), distance); double xStep = latLonRange.width() / 100.0; double yStep = latLonRange.height() / 100.0; bool hasPole = (latLonRange.top() == -90 || latLonRange.bottom() == 90); double yPos = latLonRange.top(); if (yPos != -90) { for(double xPos = latLonRange.left(); xPos <= latLonRange.right(); xPos += xStep) { if (tproj->SetGround(yPos, xPos)) { QPointF pos(tproj->XCoord(), -1 * tproj->YCoord()); boxPoly << pos; } } } double xPos = latLonRange.right(); for (double yPos = latLonRange.top(); !hasPole && yPos <= latLonRange.bottom(); yPos += yStep) { if (tproj->SetGround(yPos, xPos)) { QPointF pos(tproj->XCoord(), -1 * tproj->YCoord()); boxPoly << pos; } } yPos = latLonRange.bottom(); if (yPos != 90) { for (double xPos = latLonRange.right(); xPos >= latLonRange.left(); xPos -= xStep) { if (tproj->SetGround(yPos, xPos)) { QPointF pos(tproj->XCoord(), -1 * tproj->YCoord()); boxPoly << pos; } } } xPos = latLonRange.left(); for (double yPos = latLonRange.bottom(); !hasPole && yPos >= latLonRange.top(); yPos -= yStep) { if (tproj->SetGround(yPos, xPos)) { QPointF pos(tproj->XCoord(), -1 * tproj->YCoord()); boxPoly << pos; } } if (boxPoly.size() > 0) { boxPoly << boxPoly[0]; m_box = new QGraphicsPolygonItem(boxPoly); m_box->setZValue(DBL_MAX); getWidget()->getScene()->addItem(m_box); getWidget()->getView()->centerOn(scenePos); } } else { QString message = "Lat/Lon not within this view."; QMessageBox::information(getWidget(), "Cannot Calculate Box", message, QMessageBox::Ok); } } } } }
void SingleCellViewGraphPanelPlotWidget::drawCoordinates(QPainter *pPainter, const QPointF &pCoordinates, const QColor &pBackgroundColor, const QColor &pForegroundColor, const Location &pLocation, const bool &pCanMoveLocation) { // Retrieve the size of coordinates as they will appear on the screen, // which means using the same font as the one used for the axes pPainter->setFont(axisFont(QwtPlot::xBottom)); QString coords = QString("(%1, %2)").arg(QString::number(pCoordinates.x()), QString::number(pCoordinates.y())); QRect desktopGeometry = qApp->desktop()->availableGeometry(); QRectF coordsRect = pPainter->boundingRect(QRectF(0.0, 0.0, desktopGeometry.width(), desktopGeometry.height()), coords); // Determine where the coordinates and its background should be drawn QPoint coordinates = QPoint(canvasMap(QwtPlot::xBottom).transform(pCoordinates.x()), canvasMap(QwtPlot::yLeft).transform(pCoordinates.y())); switch (pLocation) { case TopLeft: coordsRect.moveTo(coordinates.x()-coordsRect.right()-1, coordinates.y()-coordsRect.bottom()-1); break; case TopRight: coordsRect.moveTo(coordinates.x()+2, coordinates.y()-coordsRect.bottom()-1); break; case BottomLeft: coordsRect.moveTo(coordinates.x()-coordsRect.right()-1, coordinates.y()+2); break; case BottomRight: coordsRect.moveTo(coordinates.x()+2, coordinates.y()+2); break; } if (pCanMoveLocation) { if (coordsRect.top() < 0) coordsRect.moveTop(coordinates.y()+2); if (coordsRect.left() < 0) coordsRect.moveLeft(coordinates.x()+2); if (coordsRect.bottom() > plotLayout()->canvasRect().height()) coordsRect.moveTop(coordinates.y()-coordsRect.height()-1); if (coordsRect.right() > plotLayout()->canvasRect().width()) coordsRect.moveLeft(coordinates.x()-coordsRect.width()-1); } // Draw a filled rectangle to act as the background of the coordinates // we are to show pPainter->fillRect(coordsRect, pBackgroundColor); // Draw the text for the coordinates, using a white pen QPen pen = pPainter->pen(); pen.setColor(pForegroundColor); pPainter->setPen(pen); pPainter->drawText(coordsRect, coords); }
void MainWindow::printToPage(QPainter *p, QRectF sp) { QRectF pos = sp; QRectF pos2; pos.setLeft(pos.left() + adjust->value("x", 0).toInt() - 40 ); pos.setTop( pos.top() + adjust->value("y", 0).toInt() + 300 ); if(ui->beg->text().length() > 27) { p->drawText(pos, ui->beg->text()); }else{ pos2 = pos; for(int i = 0; i < ui->beg->text().length(); i++) { pos2.setLeft(pos.left() + i * 118); p->drawText(pos2, ui->beg->text().at(i)); } } pos.setTop( pos.top() + 210 ); pos2 = pos; for(int i = 0; i < ui->begIBAN->text().remove(" ").length(); i++) { pos2.setLeft(pos.left() + i * 93); p->drawText(pos2, ui->begIBAN->text().remove(" ").at(i)); } pos.setTop( pos.top() + 210 ); pos2 = pos; for(int i = 0; i < ui->begBIC->text().length(); i++) { pos2.setLeft(pos.left() + i * 118); p->drawText(pos2, ui->begBIC->text().at(i)); } pos.setTop( pos.top() + 185); pos2 = pos; pos2.setLeft( pos2.left() + 1770 ); for(int i = 0; i < ui->betrag->text().length(); i++) { p->drawText(pos2, ui->betrag->text().at(i)); pos2.setLeft(pos2.left() + 118); } pos.setTop( pos.top() + 210); pos2 = pos; for(int i = 0; i < ui->verwendungszweck->text().length(); i++) { pos2.setLeft(pos.left() + i * 118); p->drawText(pos2, ui->verwendungszweck->text().at(i)); } pos.setTop( pos.top() + 200); pos2 = pos; if(ui->nochVerwendungszweck->text().length() > 27) { p->drawText(pos, ui->nochVerwendungszweck->text()); }else{ for(int i = 0; i < ui->nochVerwendungszweck->text().length(); i++) { pos2.setLeft(pos.left() + i * 118); p->drawText(pos2, ui->nochVerwendungszweck->text().at(i)); } } pos.setTop( pos.top() + 200); pos2 = pos; for(int i = 0; i < ui->inhaber->text().length(); i++) { pos2.setLeft(pos.left() + i * 118); p->drawText(pos2, ui->inhaber->text().at(i)); } pos.setTop( pos.top() + 200); pos2 = pos; for(int i = 0; i < ui->inhaberIBAN->text().remove(" ").length(); i++) { pos2.setLeft(pos.left() + i * 118); if(i > 1) p->drawText(pos2, ui->inhaberIBAN->text().remove(" ").at(i)); } pos.setTop( pos.top() + 350); QDate currDate = QDateTime::currentDateTime().date(); p->drawText(pos, QString( currDate.day() < 10 ? "0" : "" ) + QString::number(currDate.day()) + QString(".") + QString(currDate.month() < 10 ? "0" : "" ) + QString::number(currDate.month()) + QString(".") + QString::number(currDate.year())); }
static void clipSegmentToRect(qreal x0, qreal y0, qreal x1, qreal y1, const QRectF &clipRect, QVector<qreal> &outPoints, QVector<QPainterPath::ElementType> &outTypes) { int type0 = clipPointType(x0, y0, clipRect); int type1 = clipPointType(x1, y1, clipRect); bool accept = false; while (true) { if (!(type0 | type1)) { accept = true; break; } else if (type0 & type1) { break; } else { qreal x = 0.0; qreal y = 0.0; int outsideType = type0 ? type0 : type1; if (outsideType & BottomPoint) { x = x0 + (x1 - x0) * (clipRect.bottom() - y0) / (y1 - y0); y = clipRect.bottom() - 0.1; } else if (outsideType & TopPoint) { x = x0 + (x1 - x0) * (clipRect.top() - y0) / (y1 - y0); y = clipRect.top() + 0.1; } else if (outsideType & RightPoint) { y = y0 + (y1 - y0) * (clipRect.right() - x0) / (x1 - x0); x = clipRect.right() - 0.1; } else if (outsideType & LeftPoint) { y = y0 + (y1 - y0) * (clipRect.left() - x0) / (x1 - x0); x = clipRect.left() + 0.1; } if (outsideType == type0) { x0 = x; y0 = y; type0 = clipPointType(x0, y0, clipRect); } else { x1 = x; y1 = y; type1 = clipPointType(x1, y1, clipRect); } } } if (accept) { if (outPoints.size() >= 2) { qreal lastX, lastY; lastY = outPoints.at(outPoints.size() - 1); lastX = outPoints.at(outPoints.size() - 2); if (!qFuzzyCompare(lastY, y0) || !qFuzzyCompare(lastX, x0)) { outTypes << QPainterPath::MoveToElement; outPoints << x0 << y0; } } else { outTypes << QPainterPath::MoveToElement; outPoints << x0 << y0; } outTypes << QPainterPath::LineToElement; outPoints << x1 << y1; } }
void GlslPainter::paint(QPainter *painter, QRectF target, QQuickWindow *window) { // Need to reenable those after native painting has begun, otherwise we might // not be able to paint anything. bool stencilTestEnabled = glIsEnabled(GL_STENCIL_TEST); bool scissorTestEnabled = glIsEnabled(GL_SCISSOR_TEST); painter->beginNativePainting(); if (stencilTestEnabled) glEnable(GL_STENCIL_TEST); if (scissorTestEnabled) glEnable(GL_SCISSOR_TEST); ////////////////////////////////////////////////////////////// initTextures(); ////////////////////////////////////////////////////////////// // As seen on the telly #ifdef __GNUC__ #warning DUPLICATED CODE #endif const float textureCoordinates[] = { 0, 1, // bottom left 1, 1, // bottom right 0, 0, // top left 1, 0, // top right }; const GLfloat targetVertex[] = { GLfloat(target.left()), GLfloat(target.bottom()), GLfloat(target.right()), GLfloat(target.bottom()), GLfloat(target.left()) , GLfloat(target.top()), GLfloat(target.right()), GLfloat(target.top()) }; // const int width = window->width(); const int height = window->height(); const QTransform transform = painter->deviceTransform(); const GLfloat wfactor = 2.0 / width; const GLfloat hfactor = -2.0 / height; const GLfloat positionMatrix[4][4] = { { GLfloat(wfactor * transform.m11() - transform.m13()), GLfloat(hfactor * transform.m12() + transform.m13()), 0.0, GLfloat(transform.m13()) }, { GLfloat(wfactor * transform.m21() - transform.m23()), GLfloat(hfactor * transform.m22() + transform.m23()), 0.0, GLfloat(transform.m23()) }, { 0.0, 0.0, -1.0, 0.0 }, { GLfloat(wfactor * transform.dx() - transform.m33()), GLfloat(hfactor * transform.dy() + transform.m33()), 0.0, GLfloat(transform.m33()) } }; _program->bind(); _program->enableAttributeArray("targetVertex"); _program->enableAttributeArray("textureCoordinates"); _program->setAttributeArray("targetVertex", targetVertex, 2); _program->setAttributeArray("textureCoordinates", textureCoordinates, 2); _program->setUniformValue("positionMatrix", positionMatrix); if (_textureCount == 3) { glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, _textureIds[0]); glActiveTexture(GL_TEXTURE1); glBindTexture(GL_TEXTURE_2D, _textureIds[1]); glActiveTexture(GL_TEXTURE2); glBindTexture(GL_TEXTURE_2D, _textureIds[2]); glActiveTexture(GL_TEXTURE0); _program->setUniformValue("texY", 0); _program->setUniformValue("texU", 1); _program->setUniformValue("texV", 2); } _program->setUniformValue("colorMatrix", _colorMatrix); _program->setUniformValue("opacity", GLfloat(painter->opacity())); glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); _program->release(); painter->endNativePainting(); #if !defined(Q_OS_WIN) // TODO: FPS optional calculateFPS(); addFPSOverlay(); #endif }
static QPainterPath qwtCombinePathList( const QRectF &rect, const QList<QPainterPath> &pathList ) { if ( pathList.isEmpty() ) return QPainterPath(); QPainterPath ordered[8]; // starting top left for ( int i = 0; i < pathList.size(); i++ ) { int index = -1; QPainterPath subPath = pathList[i]; const QRectF br = pathList[i].controlPointRect(); if ( br.center().x() < rect.center().x() ) { if ( br.center().y() < rect.center().y() ) { if ( qAbs( br.top() - rect.top() ) < qAbs( br.left() - rect.left() ) ) { index = 1; } else { index = 0; } } else { if ( qAbs( br.bottom() - rect.bottom() ) < qAbs( br.left() - rect.left() ) ) { index = 6; } else { index = 7; } } if ( subPath.currentPosition().y() > br.center().y() ) qwtRevertPath( subPath ); } else { if ( br.center().y() < rect.center().y() ) { if ( qAbs( br.top() - rect.top() ) < qAbs( br.right() - rect.right() ) ) { index = 2; } else { index = 3; } } else { if ( qAbs( br.bottom() - rect.bottom() ) < qAbs( br.right() - rect.right() ) ) { index = 5; } else { index = 4; } } if ( subPath.currentPosition().y() < br.center().y() ) qwtRevertPath( subPath ); } ordered[index] = subPath; } for ( int i = 0; i < 4; i++ ) { if ( ordered[ 2 * i].isEmpty() != ordered[2 * i + 1].isEmpty() ) { // we don't accept incomplete rounded borders return QPainterPath(); } } const QPolygonF corners( rect ); QPainterPath path; //path.moveTo( rect.topLeft() ); for ( int i = 0; i < 4; i++ ) { if ( ordered[2 * i].isEmpty() ) { path.lineTo( corners[i] ); } else { path.connectPath( ordered[2 * i] ); path.connectPath( ordered[2 * i + 1] ); } } path.closeSubpath(); #if 0 return path.simplified(); #else return path; #endif }
/*! \brief Draw the identifier representing the curve on the legend \param painter Qt Painter \param rect Bounding rectangle for the identifier \sa setLegendAttribute */ void QwtPolarCurve::drawLegendIdentifier( QPainter *painter, const QRectF &rect ) const { if ( rect.isEmpty() ) return; const double dim = qMin( rect.width(), rect.height() ); QSizeF size( dim, dim ); QRectF r( 0, 0, size.width(), size.height() ); r.moveCenter( rect.center() ); if ( d_data->legendAttributes == 0 ) { QBrush brush; if ( style() != QwtPolarCurve::NoCurve ) brush = QBrush( pen().color() ); else if ( d_data->symbol && ( d_data->symbol->style() != QwtSymbol::NoSymbol ) ) { brush = QBrush( d_data->symbol->pen().color() ); } if ( brush.style() != Qt::NoBrush ) painter->fillRect( r, brush ); } if ( d_data->legendAttributes & QwtPolarCurve::LegendShowLine ) { if ( pen() != Qt::NoPen ) { painter->setPen( pen() ); QwtPainter::drawLine( painter, rect.left(), rect.center().y(), rect.right() - 1.0, rect.center().y() ); } } if ( d_data->legendAttributes & QwtPolarCurve::LegendShowSymbol ) { if ( d_data->symbol && ( d_data->symbol->style() != QwtSymbol::NoSymbol ) ) { QSize symbolSize = d_data->symbol->boundingSize(); symbolSize -= QSize( 2, 2 ); // scale the symbol size down if it doesn't fit into rect. double xRatio = 1.0; if ( rect.width() < symbolSize.width() ) xRatio = rect.width() / symbolSize.width(); double yRatio = 1.0; if ( rect.height() < symbolSize.height() ) yRatio = rect.height() / symbolSize.height(); const double ratio = qMin( xRatio, yRatio ); painter->save(); painter->scale( ratio, ratio ); d_data->symbol->drawSymbol( painter, rect.center() / ratio ); painter->restore(); } } }
/*! \brief Draw the scale */ void QwtPlotScaleItem::draw( QPainter *painter, const QwtScaleMap &xMap, const QwtScaleMap &yMap, const QRectF &canvasRect ) const { QwtScaleDraw *sd = d_data->scaleDraw; if ( d_data->scaleDivFromAxis ) { const QwtInterval interval = d_data->scaleInterval( canvasRect, xMap, yMap ); if ( interval != sd->scaleDiv().interval() ) { QwtScaleDiv scaleDiv = sd->scaleDiv(); scaleDiv.setInterval( interval ); sd->setScaleDiv( scaleDiv ); } } QPen pen = painter->pen(); pen.setStyle( Qt::SolidLine ); painter->setPen( pen ); if ( sd->orientation() == Qt::Horizontal ) { double y; if ( d_data->borderDistance >= 0 ) { if ( sd->alignment() == QwtScaleDraw::BottomScale ) y = canvasRect.top() + d_data->borderDistance; else { y = canvasRect.bottom() - d_data->borderDistance; } } else { y = yMap.transform( d_data->position ); } if ( y < canvasRect.top() || y > canvasRect.bottom() ) return; sd->move( canvasRect.left(), y ); sd->setLength( canvasRect.width() - 1 ); QwtTransform *transform = NULL; if ( xMap.transformation() ) transform = xMap.transformation()->copy(); sd->setTransformation( transform ); } else // == Qt::Vertical { double x; if ( d_data->borderDistance >= 0 ) { if ( sd->alignment() == QwtScaleDraw::RightScale ) x = canvasRect.left() + d_data->borderDistance; else { x = canvasRect.right() - d_data->borderDistance; } } else { x = xMap.transform( d_data->position ); } if ( x < canvasRect.left() || x > canvasRect.right() ) return; sd->move( x, canvasRect.top() ); sd->setLength( canvasRect.height() - 1 ); QwtTransform *transform = NULL; if ( yMap.transformation() ) transform = yMap.transformation()->copy(); sd->setTransformation( transform ); } painter->setFont( d_data->font ); sd->draw( painter, d_data->palette ); }
GRect GAppHelper::QRectF2GRect(const QRectF &other) { return GRect(other.left(), other.top(), other.right(), other.bottom()); }
static QImage qwtExpandImage(const QImage &image, const QwtScaleMap &xMap, const QwtScaleMap &yMap, const QRectF &area, const QRectF &area2, const QRectF &paintRect, const QwtInterval &xInterval, const QwtInterval &yInterval ) { const QRectF strippedRect = qwtStripRect(paintRect, area2, xMap, yMap, xInterval, yInterval); const QSize sz = strippedRect.toRect().size(); const int w = image.width(); const int h = image.height(); const QRectF r = QwtScaleMap::transform(xMap, yMap, area).normalized(); const double pw = ( r.width() - 1) / w; const double ph = ( r.height() - 1) / h; double px0, py0; if ( !xMap.isInverting() ) { px0 = xMap.transform( area2.left() ); px0 = qRound( px0 ); px0 = px0 - xMap.transform( area.left() ); } else { px0 = xMap.transform( area2.right() ); px0 = qRound( px0 ); px0 -= xMap.transform( area.right() ); px0 -= 1.0; } px0 += strippedRect.left() - paintRect.left(); if ( !yMap.isInverting() ) { py0 = yMap.transform( area2.top() ); py0 = qRound( py0 ); py0 -= yMap.transform( area.top() ); } else { py0 = yMap.transform( area2.bottom() ); py0 = qRound( py0 ); py0 -= yMap.transform( area.bottom() ); py0 -= 1.0; } py0 += strippedRect.top() - paintRect.top(); QImage expanded(sz, image.format()); switch( image.depth() ) { case 32: { for ( int y1 = 0; y1 < h; y1++ ) { int yy1; if ( y1 == 0 ) { yy1 = 0; } else { yy1 = qRound( y1 * ph - py0 ); if ( yy1 < 0 ) yy1 = 0; } int yy2; if ( y1 == h - 1 ) { yy2 = sz.height(); } else { yy2 = qRound( ( y1 + 1 ) * ph - py0 ); if ( yy2 > sz.height() ) yy2 = sz.height(); } const quint32 *line1 = reinterpret_cast<const quint32 *>( image.scanLine( y1 ) ); for ( int x1 = 0; x1 < w; x1++ ) { int xx1; if ( x1 == 0 ) { xx1 = 0; } else { xx1 = qRound( x1 * pw - px0 ); if ( xx1 < 0 ) xx1 = 0; } int xx2; if ( x1 == w - 1 ) { xx2 = sz.width(); } else { xx2 = qRound( ( x1 + 1 ) * pw - px0 ); if ( xx2 > sz.width() ) xx2 = sz.width(); } const quint32 rgb( line1[x1] ); for ( int y2 = yy1; y2 < yy2; y2++ ) { quint32 *line2 = reinterpret_cast<quint32 *>( expanded.scanLine( y2 ) ); for ( int x2 = xx1; x2 < xx2; x2++ ) line2[x2] = rgb; } } } break; } case 8: { for ( int y1 = 0; y1 < h; y1++ ) { int yy1; if ( y1 == 0 ) { yy1 = 0; } else { yy1 = qRound( y1 * ph - py0 ); if ( yy1 < 0 ) yy1 = 0; } int yy2; if ( y1 == h - 1 ) { yy2 = sz.height(); } else { yy2 = qRound( ( y1 + 1 ) * ph - py0 ); if ( yy2 > sz.height() ) yy2 = sz.height(); } const uchar *line1 = image.scanLine( y1 ); for ( int x1 = 0; x1 < w; x1++ ) { int xx1; if ( x1 == 0 ) { xx1 = 0; } else { xx1 = qRound( x1 * pw - px0 ); if ( xx1 < 0 ) xx1 = 0; } int xx2; if ( x1 == w - 1 ) { xx2 = sz.width(); } else { xx2 = qRound( ( x1 + 1 ) * pw - px0 ); if ( xx2 > sz.width() ) xx2 = sz.width(); } for ( int y2 = yy1; y2 < yy2; y2++ ) { uchar *line2 = expanded.scanLine( y2 ); memset( line2 + xx1, line1[x1], xx2 - xx1 ); } } } break; } default: expanded = image; } return expanded; }
void SingleCellViewGraphPanelPlotWidget::drawCanvas(QPainter *pPainter) { foreach (SingleCellViewGraphPanelPlotCurve *curve, mCurves) static_cast<SingleCellViewQwtCurveDataAdaptor*>(curve->data())->updateSize(); switch (mAction) { case ShowCoordinates: { // We are showing some coordinates, so start by drawing our pixmap pPainter->drawPixmap(0, 0, mCanvasPixmap); // Draw the two dashed lines that show the coordinates, using a dark // cyan pen QPen pen = pPainter->pen(); QColor backgroundColor = Qt::darkCyan; backgroundColor.setAlphaF(0.69); pen.setColor(backgroundColor); pen.setStyle(Qt::DashLine); pPainter->setPen(pen); QPointF coordinates = QPointF(canvasMap(QwtPlot::xBottom).transform(mOriginPoint.x()), canvasMap(QwtPlot::yLeft).transform(mOriginPoint.y())); pPainter->drawLine(0.0, coordinates.y(), plotLayout()->canvasRect().width(), coordinates.y()); pPainter->drawLine(coordinates.x(), 0.0, coordinates.x(), plotLayout()->canvasRect().height()); // Draw the coordinates drawCoordinates(pPainter, mOriginPoint, backgroundColor, Qt::white); break; } case ZoomRegion: { // We are zooming a region, so start by drawing our pixmap pPainter->drawPixmap(0, 0, mCanvasPixmap); // Retrieve the coordinates of the region to be zoomed QRectF zoomRegionRect = zoomRegion(); // Now, draw the region to be zoomed QColor penColor = Qt::darkRed; QColor brushColor = Qt::yellow; penColor.setAlphaF(0.69); brushColor.setAlphaF(0.19); pPainter->setPen(penColor); QwtScaleMap canvasMapX = canvasMap(QwtPlot::xBottom); QwtScaleMap canvasMapY = canvasMap(QwtPlot::yLeft); double left = canvasMapX.transform(zoomRegionRect.left()); double top = canvasMapY.transform(zoomRegionRect.top()); QRectF unmappedZoomRegionRect = QRectF(left, top, canvasMapX.transform(zoomRegionRect.right())-left, canvasMapY.transform(zoomRegionRect.bottom())-top); pPainter->fillRect(unmappedZoomRegionRect, brushColor); pPainter->drawRect(unmappedZoomRegionRect); // Draw the two sets of coordinates drawCoordinates(pPainter, zoomRegionRect.topLeft(), penColor, Qt::white, BottomRight, false); drawCoordinates(pPainter, zoomRegionRect.bottomRight(), penColor, Qt::white, TopLeft, false); break; } default: // We aren't doing anything special, so just draw our canvas normally QwtPlot::drawCanvas(pPainter); } }
void QwtPlotLayout::alignScales( int options, QRectF &canvasRect, QRectF scaleRect[QwtPlot::axisCnt] ) const { int backboneOffset[QwtPlot::axisCnt]; for ( int axis = 0; axis < QwtPlot::axisCnt; axis++ ) { backboneOffset[axis] = 0; if ( !d_data->alignCanvasToScales ) backboneOffset[axis] += d_data->canvasMargin[axis]; if ( !( options & IgnoreFrames ) ) backboneOffset[axis] += d_data->layoutData.canvas.frameWidth; } for ( int axis = 0; axis < QwtPlot::axisCnt; axis++ ) { if ( !scaleRect[axis].isValid() ) continue; const int startDist = d_data->layoutData.scale[axis].start; const int endDist = d_data->layoutData.scale[axis].end; QRectF &axisRect = scaleRect[axis]; if ( axis == QwtPlot::xTop || axis == QwtPlot::xBottom ) { const QRectF &leftScaleRect = scaleRect[QwtPlot::yLeft]; const int leftOffset = backboneOffset[QwtPlot::yLeft] - startDist; if ( leftScaleRect.isValid() ) { const int dx = leftOffset + leftScaleRect.width(); if ( d_data->alignCanvasToScales && dx < 0 ) { /* The axis needs more space than the width of the left scale. */ canvasRect.setLeft( qMax( canvasRect.left(), axisRect.left() - dx ) ); } else { const double minLeft = leftScaleRect.left(); const double left = axisRect.left() + leftOffset; axisRect.setLeft( qMax( left, minLeft ) ); } } else { if ( d_data->alignCanvasToScales && leftOffset < 0 ) { canvasRect.setLeft( qMax( canvasRect.left(), axisRect.left() - leftOffset ) ); } else { if ( leftOffset > 0 ) axisRect.setLeft( axisRect.left() + leftOffset ); } } const QRectF &rightScaleRect = scaleRect[QwtPlot::yRight]; const int rightOffset = backboneOffset[QwtPlot::yRight] - endDist + 1; if ( rightScaleRect.isValid() ) { const int dx = rightOffset + rightScaleRect.width(); if ( d_data->alignCanvasToScales && dx < 0 ) { /* The axis needs more space than the width of the right scale. */ canvasRect.setRight( qMin( canvasRect.right(), axisRect.right() + dx ) ); } const double maxRight = rightScaleRect.right(); const double right = axisRect.right() - rightOffset; axisRect.setRight( qMin( right, maxRight ) ); } else { if ( d_data->alignCanvasToScales && rightOffset < 0 ) { canvasRect.setRight( qMin( canvasRect.right(), axisRect.right() + rightOffset ) ); } else { if ( rightOffset > 0 ) axisRect.setRight( axisRect.right() - rightOffset ); } } } else // QwtPlot::yLeft, QwtPlot::yRight { const QRectF &bottomScaleRect = scaleRect[QwtPlot::xBottom]; const int bottomOffset = backboneOffset[QwtPlot::xBottom] - endDist + 1; if ( bottomScaleRect.isValid() ) { const int dy = bottomOffset + bottomScaleRect.height(); if ( d_data->alignCanvasToScales && dy < 0 ) { /* The axis needs more space than the height of the bottom scale. */ canvasRect.setBottom( qMin( canvasRect.bottom(), axisRect.bottom() + dy ) ); } else { const double maxBottom = bottomScaleRect.top() + d_data->layoutData.scale[QwtPlot::xBottom].tickOffset; const double bottom = axisRect.bottom() - bottomOffset; axisRect.setBottom( qMin( bottom, maxBottom ) ); } } else { if ( d_data->alignCanvasToScales && bottomOffset < 0 ) { canvasRect.setBottom( qMin( canvasRect.bottom(), axisRect.bottom() + bottomOffset ) ); } else { if ( bottomOffset > 0 ) axisRect.setBottom( axisRect.bottom() - bottomOffset ); } } const QRectF &topScaleRect = scaleRect[QwtPlot::xTop]; const int topOffset = backboneOffset[QwtPlot::xTop] - startDist; if ( topScaleRect.isValid() ) { const int dy = topOffset + topScaleRect.height(); if ( d_data->alignCanvasToScales && dy < 0 ) { /* The axis needs more space than the height of the top scale. */ canvasRect.setTop( qMax( canvasRect.top(), axisRect.top() - dy ) ); } else { const double minTop = topScaleRect.bottom() - d_data->layoutData.scale[QwtPlot::xTop].tickOffset; const double top = axisRect.top() + topOffset; axisRect.setTop( qMax( top, minTop ) ); } } else { if ( d_data->alignCanvasToScales && topOffset < 0 ) { canvasRect.setTop( qMax( canvasRect.top(), axisRect.top() - topOffset ) ); } else { if ( topOffset > 0 ) axisRect.setTop( axisRect.top() + topOffset ); } } } } if ( d_data->alignCanvasToScales ) { /* The canvas has been aligned to the scale with largest border distances. Now we have to realign the other scale. */ int fw = 0; if ( !( options & IgnoreFrames ) ) fw = d_data->layoutData.canvas.frameWidth; for ( int axis = 0; axis < QwtPlot::axisCnt; axis++ ) { if ( !scaleRect[axis].isValid() ) continue; if ( axis == QwtPlot::xBottom || axis == QwtPlot::xTop ) { scaleRect[axis].setLeft( canvasRect.left() + fw - d_data->layoutData.scale[axis].start ); scaleRect[axis].setRight( canvasRect.right() - fw - 1 + d_data->layoutData.scale[axis].end ); } else { scaleRect[axis].setTop( canvasRect.top() + fw - d_data->layoutData.scale[axis].start ); scaleRect[axis].setBottom( canvasRect.bottom() - fw - 1 + d_data->layoutData.scale[axis].end ); } } if ( scaleRect[QwtPlot::xTop].isValid() ) scaleRect[QwtPlot::xTop].setBottom( canvasRect.top() ); if ( scaleRect[QwtPlot::xBottom].isValid() ) scaleRect[QwtPlot::xBottom].setTop( canvasRect.bottom() ); if ( scaleRect[QwtPlot::yLeft].isValid() ) scaleRect[QwtPlot::yLeft].setRight( canvasRect.left() ); if ( scaleRect[QwtPlot::yRight].isValid() ) scaleRect[QwtPlot::yRight].setLeft( canvasRect.right() ); } }
void SingleCellViewGraphPanelPlotWidget::setLocalAxes(const double &pLocalMinX, const double &pLocalMaxX, const double &pLocalMinY, const double &pLocalMaxY, const bool &pCanReplot, const bool &pForceMinMaxValues, const bool &pUpdateMinMaxValues, const bool &pResetMinMaxValues) { // Update our axes double oldLocalMinX = localMinX(); double oldLocalMaxX = localMaxX(); double oldLocalMinY = localMinY(); double oldLocalMaxY = localMaxY(); double newLocalMinX = pLocalMinX; double newLocalMaxX = pLocalMaxX; double newLocalMinY = pLocalMinY; double newLocalMaxY = pLocalMaxY; // Retrieve the bounding rectangle for all our curves (but only for those // that have some data) QRectF boundingRect = QRectF(); foreach (SingleCellViewGraphPanelPlotCurve *curve, mCurves) if (curve->dataSize()) boundingRect |= curve->boundingRect(); // Update the minimum/maximum values of our axes, should we have retrieved a // valid bounding rectangle if (boundingRect != QRectF()) { // Optimise our bounding rectangle by first retrieving the // minimum/maximum values of our axes double xMin = boundingRect.left(); double xMax = boundingRect.right(); double yMin = boundingRect.top(); double yMax = boundingRect.bottom(); // Make sure that the minimum/maximum values of our axes have finite // values checkAnyAxesValues(xMin, xMax, yMin, yMax); // Optimise the minimum/maximum values of our axes by rounding them // down/up, respectively double powerX = qPow(10.0, qMax(xMin?qFloor(log10(qAbs(xMin))):0, xMax?qFloor(log10(qAbs(xMax))):0)); double powerY = qPow(10.0, qMax(yMin?qFloor(log10(qAbs(yMin))):0, yMax?qFloor(log10(qAbs(yMax))):0)); xMin = powerX*qFloor(xMin/powerX); xMax = powerX*qCeil(xMax/powerX); yMin = powerY*qFloor(yMin/powerY); yMax = powerY*qCeil(yMax/powerY); // Make sure that the optimised minimum/maximum values of our axes have // finite values checkAnyAxesValues(xMin, xMax, yMin, yMax); // Update the minimum/maximum values of our axes, if required if (!mFixedAxisX) { if (pResetMinMaxValues) setMinMaxX(xMin, xMax); else if (pUpdateMinMaxValues) setMinMaxX(qMin(mMinX, xMin), qMax(mMaxX, xMax)); } if (!mFixedAxisY) { if (pResetMinMaxValues) setMinMaxY(yMin, yMax); else if (pUpdateMinMaxValues) setMinMaxY(qMin(mMinY, yMin), qMax(mMaxY, yMax)); } } // Make sure that the new minimum/maximum values of our local axes fit // within the minimum/maximum values of our axes if (pForceMinMaxValues) { newLocalMinX = mMinX; newLocalMaxX = mMaxX; newLocalMinY = mMinY; newLocalMaxY = mMaxY; } else { newLocalMinX = qMax(newLocalMinX, mMinX); newLocalMaxX = qMin(newLocalMaxX, mMaxX); newLocalMinY = qMax(newLocalMinY, mMinY); newLocalMaxY = qMin(newLocalMaxY, mMaxY); } // Make sure that the new minimum/maximum values of our local axes have // finite values checkAnyAxesValues(newLocalMinX, newLocalMaxX, newLocalMinY, newLocalMaxY); // Make sure that the new minimum/maximum values of our local axes have a // valid zoom factor checkLocalAxisValues(QwtPlot::xBottom, newLocalMinX, newLocalMaxX); checkLocalAxisValues(QwtPlot::yLeft, newLocalMinY, newLocalMaxY); // Update the minimum/maximum values of our local axes, if needed bool needReplot = false; if ((newLocalMinX != oldLocalMinX) || (newLocalMaxX != oldLocalMaxX)) { setLocalMinMaxX(newLocalMinX, newLocalMaxX); needReplot = true; } if ((newLocalMinY != oldLocalMinY) || (newLocalMaxY != oldLocalMaxY)) { setLocalMinMaxY(newLocalMinY, newLocalMaxY); needReplot = true; } // Replot ourselves, if needed and allowed if (needReplot && pCanReplot) replotNow(); }
NATRON_NAMESPACE_ENTER QImage NodeGraph::getFullSceneScreenShot() { _imp->isDoingPreviewRender = true; // The bbox of all nodes in the nodegraph QRectF sceneR = _imp->calcNodesBoundingRect(); // The visible portion of the nodegraph QRectF viewRect = visibleSceneRect(); // Make sure the visible rect is included in the scene rect sceneR = sceneR.united(viewRect); int navWidth = std::ceil(width() * NATRON_NAVIGATOR_BASE_WIDTH); int navHeight = std::ceil(height() * NATRON_NAVIGATOR_BASE_HEIGHT); // Make sceneR and viewRect keep the same aspect ratio as the navigator double xScale = navWidth / sceneR.width(); double yScale = navHeight / sceneR.height(); double scaleFactor = std::max( 0.001, std::min(xScale, yScale) ); int sceneW_navPixelCoord = std::floor(sceneR.width() * scaleFactor); int sceneH_navPixelCoord = std::floor(sceneR.height() * scaleFactor); // Render the scene in an image with the same aspect ratio as the scene rect QImage renderImage(sceneW_navPixelCoord, sceneH_navPixelCoord, QImage::Format_ARGB32_Premultiplied); // Fill the background renderImage.fill( QColor(71, 71, 71, 255) ); // Offset the visible rect corner as an offset relative to the scene rect corner viewRect.setX( viewRect.x() - sceneR.x() ); viewRect.setY( viewRect.y() - sceneR.y() ); viewRect.setWidth( viewRect.width() - sceneR.x() ); viewRect.setHeight( viewRect.height() - sceneR.y() ); QRectF viewRect_navCoordinates = viewRect; viewRect_navCoordinates.setLeft(viewRect.left() * scaleFactor); viewRect_navCoordinates.setBottom(viewRect.bottom() * scaleFactor); viewRect_navCoordinates.setRight(viewRect.right() * scaleFactor); viewRect_navCoordinates.setTop(viewRect.top() * scaleFactor); // Paint the visible portion with a highlight QPainter painter(&renderImage); // Remove the overlays from the scene before rendering it scene()->removeItem(_imp->_cacheSizeText); scene()->removeItem(_imp->_navigator); // Render into the QImage with downscaling scene()->render(&painter, renderImage.rect(), sceneR, Qt::KeepAspectRatio); // Add the overlays back scene()->addItem(_imp->_navigator); scene()->addItem(_imp->_cacheSizeText); // Fill the highlight with a semi transparent whitish grey painter.fillRect( viewRect_navCoordinates, QColor(200, 200, 200, 100) ); // Draw a border surrounding the QPen p; p.setWidth(2); p.setBrush(Qt::yellow); painter.setPen(p); // Make sure the border is visible viewRect_navCoordinates.adjust(2, 2, -2, -2); painter.drawRect(viewRect_navCoordinates); // Now make an image of the requested size of the navigator and center the render image into it QImage img(navWidth, navHeight, QImage::Format_ARGB32_Premultiplied); img.fill( QColor(71, 71, 71, 255) ); int xOffset = ( img.width() - renderImage.width() ) / 2; int yOffset = ( img.height() - renderImage.height() ) / 2; int dstY = yOffset; for (int srcY = 0; srcY < renderImage.height(); ++srcY, ++dstY) { if ( dstY < 0 || dstY >= img.height() ) { break; } QRgb* dst_pixels = (QRgb*)img.scanLine(dstY); assert(dst_pixels); const QRgb* src_pixels = (const QRgb*)renderImage.scanLine(srcY); assert(src_pixels); int dstX = xOffset; for (int srcX = 0; srcX < renderImage.width(); ++srcX, ++dstX) { if ( dstX < 0 || dstX >= img.width() ) { dst_pixels[dstX] = qRgba(0, 0, 0, 0); } else { dst_pixels[dstX] = src_pixels[srcX]; } } } _imp->isDoingPreviewRender = false; return img; } // getFullSceneScreenShot
void RangeHistogram::paintEvent(QPaintEvent *e) { QPainter p(this); p.setRenderHint(QPainter::Antialiasing); const QBrush blackBrush(QColor(0, 0, 0)); const QBrush redBrush(QColor(60, 0, 0)); const QBrush greenBrush(QColor(0, 128, 0)); const QBrush whiteBrush(QColor(255, 255, 255)); QRectF r = rect(); p.eraseRect(r); r = r.marginsRemoved(QMarginsF(m_Margin, m_Margin, m_Margin, m_Margin)); p.fillRect(r, palette().brush(QPalette::Shadow)); QMarginsF border(m_Border, m_Border, m_Border, m_Border); border /= devicePixelRatioF(); r = r.marginsRemoved(border); p.fillRect(r, ValidRange() ? palette().brush(QPalette::Inactive, QPalette::Highlight) : redBrush); int whiteX = (int)(whiteDelta() * r.width()); int blackX = (int)(blackDelta() * r.width() + 0.5); QRectF blackPoint(r.topLeft(), QSize(blackX, r.height())); QRectF whitePoint(r.left() + whiteX, r.top(), r.width() - whiteX, r.height()); if(ValidRange()) { p.setPen(QPen(palette().color(QPalette::Dark))); p.drawLine(blackPoint.topRight(), blackPoint.bottomRight()); p.drawLine(whitePoint.topLeft(), whitePoint.bottomLeft()); } p.fillRect(whitePoint, whiteBrush); p.fillRect(blackPoint, blackBrush); if(!ValidRange()) return; if(!m_HistogramData.isEmpty()) { float minx = delta(m_HistogramMin); float maxx = delta(m_HistogramMax); uint32_t maxval = 0; for(int i = 0; i < m_HistogramData.count(); i++) { float x = (float)i / (float)m_HistogramData.count(); float xdelta = minx + x * (maxx - minx); if(xdelta >= 0.0f && xdelta <= 1.0f) { maxval = qMax(maxval, m_HistogramData[i]); } } if(maxval == 0) maxval = 1; for(int i = 0; i < m_HistogramData.count(); i++) { float x = (float)i / (float)m_HistogramData.count(); float y = (float)m_HistogramData[i] / (float)maxval; float xdelta = minx + x * (maxx - minx); if(xdelta >= 0.0f && xdelta <= 1.0f) { float segwidth = qMax(r.width() * (maxx - minx) / (float)m_HistogramData.count(), 1.0); QRectF barRect(QPointF(r.left() + r.width() * (minx + x * (maxx - minx)), r.bottom() - r.height() * y + 1), QSizeF(segwidth, r.height() * y)); p.fillRect(barRect, greenBrush); } } } QVector<QPointF> blackTriangle = {QPoint(blackPoint.right(), m_MarkerSize * 2), QPoint(blackPoint.right() + m_MarkerSize, 0), QPoint(blackPoint.right() - m_MarkerSize, 0)}; QPainterPath blackPath; blackPath.addPolygon(QPolygonF(blackTriangle)); p.fillPath(blackPath, palette().brush(QPalette::Dark)); QVector<QPointF> whiteTriangle = { QPoint(whitePoint.left(), whitePoint.bottom() - m_MarkerSize * 2 + m_Margin), QPoint(whitePoint.left() + m_MarkerSize, whitePoint.bottom() + m_Margin), QPoint(whitePoint.left() - m_MarkerSize, whitePoint.bottom() + m_Margin)}; QPainterPath whitePath; whitePath.addPolygon(QPolygonF(whiteTriangle)); p.fillPath(whitePath, palette().brush(QPalette::Dark)); blackTriangle[0] -= QPointF(0.0, 2.0) / devicePixelRatioF(); blackTriangle[1] += QPointF(-2.0, 1.0) / devicePixelRatioF(); blackTriangle[2] += QPointF(2.0, 1.0) / devicePixelRatioF(); blackPath = QPainterPath(); blackPath.addPolygon(QPolygonF(blackTriangle)); whiteTriangle[0] += QPointF(0.0, 2.0) / devicePixelRatioF(); whiteTriangle[1] -= QPointF(2.0, 1.0) / devicePixelRatioF(); whiteTriangle[2] += QPointF(2.0, -1.0) / devicePixelRatioF(); whitePath = QPainterPath(); whitePath.addPolygon(QPolygonF(whiteTriangle)); p.fillPath(blackPath, blackBrush); p.fillPath(whitePath, whiteBrush); }
//----------------------------------------------------------------------- // Class MacroItem //----------------------------------------------------------------------- void MacroItem::paint(QPainter* painter, const QStyleOptionGraphicsItem* option, QWidget* widget) { app::Macro::Ptr macroInstance = vertex().dataRef().staticCast<app::Macro>(); Q_ASSERT(!macroInstance.isNull()); graph::VertexItem::paint(painter,option,widget); QRectF rcInner = innerRect(); // calculate text sizes QString macroName = macroInstance->getName(); QFontMetrics fmName(*Resource::font(Resource::FONT_MACRONAME)); QRect rectName = fmName.boundingRect(macroName); QString macroRuntime = macroInstance->getRuntimeString(); QFontMetrics fmStatus(*Resource::font(Resource::FONT_MACROSTATUS)); QRect rectRuntime = fmStatus.boundingRect("000.000 ms"); QPixmap statusIcon; switch(macroInstance->getState()) { case app::Macro::Idle: statusIcon = QPixmap(":/icons/resources/bullet_black.png"); break; case app::Macro::Running: statusIcon = QPixmap(":/icons/resources/bullet_orange.png"); break; case app::Macro::Ok: if (!toolTip().isEmpty()) setToolTip(QString()); statusIcon = QPixmap(":/icons/resources/bullet_green.png"); break; case app::Macro::Failure: setToolTip(macroInstance->getErrorMsg()); statusIcon = QPixmap(":/icons/resources/bullet_red.png"); break; } QString macroOrder = QString(QObject::tr("Order No.: ")); if (vertex().topologicalOrder() >= 0) { macroOrder += QString("%1").arg(vertex().topologicalOrder()); } else { macroOrder += '-'; } QPixmap orderStatus; if (vertex().isInCycle() && vertex().topologicalOrder() == 0 && vertex().topologicalOrderForced()) { orderStatus = QPixmap(":/icons/resources/anchor.png"); } else if (vertex().isInCycle() && vertex().topologicalOrder() < 0 && !vertex().topologicalOrderForced()) { orderStatus = QPixmap(":/icons/resources/cycle.png"); } else if (!vertex().isInCycle() && vertex().topologicalOrder() < 0) { orderStatus = QPixmap(":/icons/resources/error.png"); } QRect rectOrder = fmStatus.boundingRect(macroOrder); rectOrder.adjust(0,0,orderStatus.width(),16 - rectOrder.height()); // paint macro name QRectF rcTextName(rcInner.left(),rcInner.top(),rcInner.width(),(qreal)rectName.height()); painter->setPen(QPen(Qt::black)); painter->setFont(*Resource::font(Resource::FONT_MACRONAME)); painter->drawText(rcTextName,Qt::AlignCenter,macroName); // paint runtime including indicator QRectF rcTextRuntime(rcInner.left() + rcInner.width() * 0.02 + statusIcon.width(),rcInner.top() + rectName.height() + 1.0,rcInner.width() - 2 * rcInner.width() * 0.02 - statusIcon.width(),(qreal)rectRuntime.height()); painter->setPen(QPen(Qt::blue)); painter->setFont(*Resource::font(Resource::FONT_MACROSTATUS)); painter->setClipRect(rcTextRuntime); painter->drawText(rcTextRuntime,Qt::AlignRight,macroRuntime); painter->setClipRect(rcInner); painter->drawPixmap(rcInner.left() + rcInner.width() * 0.02,rcTextRuntime.top(),statusIcon.rect().width(),statusIcon.rect().height(),statusIcon); // paint topological order QRectF rcTextOrder(rcInner.left() + orderStatus.rect().width() + (rcInner.width() - rectOrder.width()) / 2.0,rcInner.bottom() - (qreal)rectOrder.height(),rcInner.width(),(qreal)rectOrder.height()); painter->setPen(QPen(Qt::black)); painter->drawText(rcTextOrder,Qt::AlignLeft,macroOrder); if (!orderStatus.isNull()) { painter->drawPixmap(rcTextOrder.left() - orderStatus.rect().width() - 1.0,rcTextOrder.top(),orderStatus.rect().width(),orderStatus.rect().height(),orderStatus); } painter->setClipRect(itemRect()); }
void IsometricRenderer::drawMapObject(QPainter *painter, const MapObject *object, const QColor &color) const { painter->save(); QPen pen(Qt::black); pen.setCosmetic(true); const Cell &cell = object->cell(); if (!cell.isEmpty()) { const Tile *tile = cell.tile; const QSize imgSize = tile->size(); const QPointF pos = pixelToScreenCoords(object->position()); const QPointF tileOffset = tile->tileset()->tileOffset(); // Draw the name before the transform is applied const QFontMetrics fm = painter->fontMetrics(); QString name = fm.elidedText(object->name(), Qt::ElideRight, imgSize.width() + 2); if (!name.isEmpty()) { const QPointF textPos = pos + tileOffset - QPointF(imgSize.width() / 2, 5 + imgSize.height()); painter->drawText(textPos + QPointF(1, 1), name); painter->setPen(color); painter->drawText(textPos, name); } CellRenderer(painter).render(cell, pos, CellRenderer::BottomCenter); if (testFlag(ShowTileObjectOutlines)) { QRectF rect(QPointF(pos.x() - imgSize.width() / 2 + tileOffset.x(), pos.y() - imgSize.height() + tileOffset.y()), imgSize); pen.setStyle(Qt::SolidLine); painter->setPen(pen); painter->drawRect(rect); pen.setStyle(Qt::DotLine); pen.setColor(color); painter->setPen(pen); painter->drawRect(rect); } } else { const qreal lineWidth = objectLineWidth(); const qreal scale = painterScale(); const qreal shadowOffset = (lineWidth == 0 ? 1 : lineWidth) / scale; QColor brushColor = color; brushColor.setAlpha(50); QBrush brush(brushColor); pen.setJoinStyle(Qt::RoundJoin); pen.setCapStyle(Qt::RoundCap); pen.setWidth(lineWidth); painter->setPen(pen); painter->setRenderHint(QPainter::Antialiasing); // TODO: Draw the object name // TODO: Do something sensible to make null-sized objects usable switch (object->shape()) { case MapObject::Ellipse: { QPointF topLeft(pixelToScreenCoords(object->bounds().topLeft())); QPointF bottomLeft(pixelToScreenCoords(object->bounds().bottomLeft())); QPointF topRight(pixelToScreenCoords(object->bounds().topRight())); const qreal headerX = bottomLeft.x(); const qreal headerY = topLeft.y(); QRectF rect(bottomLeft, topRight); const QFontMetrics fm = painter->fontMetrics(); QString name = fm.elidedText(object->name(), Qt::ElideRight, rect.width() + 2); QPolygonF polygon = pixelRectToScreenPolygon(object->bounds()); float tw = map()->tileWidth(); float th = map()->tileHeight(); QPointF transformScale(1, 1); if (tw > th) transformScale = QPointF(1, th/tw); else transformScale = QPointF(tw/th, 1); QPointF l1 = polygon.at(1) - polygon.at(0); QPointF l2 = polygon.at(3) - polygon.at(0); QTransform trans; trans.scale(transformScale.x(), transformScale.y()); trans.rotate(45); QTransform iTrans = trans.inverted(); QPointF l1x = iTrans.map(l1); QPointF l2x = iTrans.map(l2); QSizeF ellipseSize(l1x.manhattanLength(), l2x.manhattanLength()); if (ellipseSize.width() > 0 && ellipseSize.height() > 0) { painter->save(); painter->setPen(pen); painter->translate(polygon.at(0)); painter->scale(transformScale.x(), transformScale.y()); painter->rotate(45); painter->drawEllipse(QRectF(QPointF(0, 0), ellipseSize)); painter->restore(); } painter->setBrush(Qt::NoBrush); painter->drawPolygon(polygon); if (!name.isEmpty()) painter->drawText(QPoint(headerX, headerY - 5), name); pen.setColor(color); painter->setPen(pen); painter->setBrush(Qt::NoBrush); painter->translate(QPointF(0, -shadowOffset)); painter->drawPolygon(polygon); painter->setBrush(brush); if (ellipseSize.width() > 0 && ellipseSize.height() > 0) { painter->save(); painter->translate(polygon.at(0)); painter->scale(transformScale.x(), transformScale.y()); painter->rotate(45); painter->drawEllipse(QRectF(QPointF(0, 0), ellipseSize)); painter->restore(); } if (!name.isEmpty()) painter->drawText(QPoint(headerX, headerY - 5), name); break; } case MapObject::Rectangle: { QPointF topLeft(pixelToScreenCoords(object->bounds().topLeft())); QPointF bottomLeft(pixelToScreenCoords(object->bounds().bottomLeft())); QPointF topRight(pixelToScreenCoords(object->bounds().topRight())); const qreal headerX = bottomLeft.x(); const qreal headerY = topLeft.y(); QRectF rect(bottomLeft, topRight); const QFontMetrics fm = painter->fontMetrics(); QString name = fm.elidedText(object->name(), Qt::ElideRight, rect.width() + 2); QPolygonF polygon = pixelRectToScreenPolygon(object->bounds()); painter->drawPolygon(polygon); if (!name.isEmpty()) painter->drawText(QPointF(headerX, headerY - 5 + shadowOffset), name); pen.setColor(color); painter->setPen(pen); painter->setBrush(brush); polygon.translate(0, -shadowOffset); painter->drawPolygon(polygon); if (!name.isEmpty()) painter->drawText(QPointF(headerX, headerY - 5), name); break; } case MapObject::Polygon: { const QPointF &pos = object->position(); const QPolygonF polygon = object->polygon().translated(pos); QPolygonF screenPolygon = pixelToScreenCoords(polygon); const QRectF polygonBoundingRect = screenPolygon.boundingRect(); const QFontMetrics fm = painter->fontMetrics(); QString name = fm.elidedText(object->name(), Qt::ElideRight, polygonBoundingRect.width() + 2); if (!name.isEmpty()) painter->drawText(QPointF(polygonBoundingRect.left(), polygonBoundingRect.top() - 5 + shadowOffset), name); painter->drawPolygon(screenPolygon); pen.setColor(color); painter->setPen(pen); painter->setBrush(brush); screenPolygon.translate(0, -shadowOffset); painter->drawPolygon(screenPolygon); if (!name.isEmpty()) painter->drawText(QPointF(polygonBoundingRect.left(), polygonBoundingRect.top() - 5), name); break; } case MapObject::Polyline: { const QPointF &pos = object->position(); const QPolygonF polygon = object->polygon().translated(pos); QPolygonF screenPolygon = pixelToScreenCoords(polygon); painter->drawPolyline(screenPolygon); pen.setColor(color); painter->setPen(pen); screenPolygon.translate(0, -shadowOffset); painter->drawPolyline(screenPolygon); break; } } } painter->restore(); }
void MacroPinItem::paint(QPainter* painter, const QStyleOptionGraphicsItem* /*option*/, QWidget* /*widget*/) { graph::VertexItem* vertexItem = static_cast<graph::VertexItem*>(parentItem()); Q_ASSERT(vertexItem != 0); const graph::Palette& pal = palette(); QRectF rect = boundingRect(); switch(vertexItem->itemLayout()) { case graph::Defines::TopToBottom: { QPainterPath pinPath; if (pin().direction() == graph::Defines::Incoming) { painter->setPen(pal.pen(graph::Palette::PinIncomingBorder)); pinPath.moveTo(rect.right(),rect.top() + rect.height() / 2.0); pinPath.lineTo(rect.topRight()); pinPath.lineTo(rect.topLeft()); pinPath.lineTo(rect.left(),rect.top() + rect.height() / 2.0); pinPath.arcTo(rect,180.0,180.0); pinPath.closeSubpath(); painter->setBrush(pal.brush(graph::Palette::PinIncomingFill)); painter->drawPath(pinPath); } else { painter->setPen(pal.pen(graph::Palette::PinOutgoingBorder)); pinPath.moveTo(rect.right(),rect.top() + rect.height() / 2.0); pinPath.lineTo(rect.bottomRight()); pinPath.lineTo(rect.bottomLeft()); pinPath.lineTo(rect.left(),rect.top() + rect.height() / 2.0); pinPath.arcTo(rect,180.0,-180.0); pinPath.closeSubpath(); painter->setBrush(pal.brush(graph::Palette::PinOutgoingFill)); painter->drawPath(pinPath); } break; } case graph::Defines::LeftToRight: { QPainterPath pinPath; if (pin().direction() == graph::Defines::Incoming) { painter->setPen(pal.pen(graph::Palette::PinIncomingBorder)); pinPath.moveTo(rect.left() + rect.width() / 2.0,rect.top()); pinPath.lineTo(rect.topLeft()); pinPath.lineTo(rect.bottomLeft()); pinPath.lineTo(rect.left() + rect.width() / 2.0,rect.bottom()); pinPath.arcTo(rect,270.0,180.0); pinPath.closeSubpath(); painter->setBrush(pal.brush(graph::Palette::PinIncomingFill)); painter->drawPath(pinPath); } else { painter->setPen(pal.pen(graph::Palette::PinOutgoingBorder)); pinPath.moveTo(rect.left() + rect.width() / 2.0,rect.top()); pinPath.lineTo(rect.topRight()); pinPath.lineTo(rect.bottomRight()); pinPath.lineTo(rect.left() + rect.width() / 2.0,rect.bottom()); pinPath.arcTo(rect,270.0,-180.0); pinPath.closeSubpath(); painter->setBrush(pal.brush(graph::Palette::PinOutgoingFill)); painter->drawPath(pinPath); } break; } case graph::Defines::RightToLeft: { QPainterPath pinPath; if (pin().direction() == graph::Defines::Incoming) { painter->setPen(pal.pen(graph::Palette::PinIncomingBorder)); pinPath.moveTo(rect.left() + rect.width() / 2.0,rect.top()); pinPath.lineTo(rect.topRight()); pinPath.lineTo(rect.bottomRight()); pinPath.lineTo(rect.left() + rect.width() / 2.0,rect.bottom()); pinPath.arcTo(rect,270.0,-180.0); pinPath.closeSubpath(); painter->setBrush(pal.brush(graph::Palette::PinIncomingFill)); painter->drawPath(pinPath); } else { painter->setPen(pal.pen(graph::Palette::PinOutgoingBorder)); pinPath.moveTo(rect.left() + rect.width() / 2.0,rect.top()); pinPath.lineTo(rect.topLeft()); pinPath.lineTo(rect.bottomLeft()); pinPath.lineTo(rect.left() + rect.width() / 2.0,rect.bottom()); pinPath.arcTo(rect,270.0,180.0); pinPath.closeSubpath(); painter->setBrush(pal.brush(graph::Palette::PinOutgoingFill)); painter->drawPath(pinPath); } break; } } }
void acCustomGraphicsScene::drawBackground(QPainter *painter, const QRectF &rect) { // color Black QColor ColorBlack(0, 0, 0); // color White QColor ColorWhite(255, 255, 255); // Draw a line grid if (m_gridenabled != eCustomGraphicsScene_Grids::None) { painter->setPen(Qt::white); // Start point for Horizonal steps qreal startH = 0; //Start point for Virtical steps qreal startV = 0; switch (m_gridenabled) { case eCustomGraphicsScene_Grids::Block: { QImage image(":/CompressonatorGUI/Images/GridSolid.png"); QBrush brush(image); painter->fillRect(rect, brush); break; } case eCustomGraphicsScene_Grids::Lines: { // First fill the BackGround as black painter->fillRect(rect, ColorBlack); // draw horizontal grid lines painter->setPen(QPen(ColorWhite)); for (qreal y = startH; y < rect.bottom();) { y += m_gridStep; painter->drawLine(rect.left(), y, rect.right(), y); } // draw virtical grid lines for (qreal x = startV; x < rect.right();) { x += m_gridStep; painter->drawLine(x, rect.top(), x, rect.bottom()); } break; } case eCustomGraphicsScene_Grids::Dots: { // First fill the BackGround as black painter->fillRect(rect, ColorBlack); // draw points painter->setPen(QPen(ColorWhite)); for (qreal y = startH; y < rect.bottom();) { y += m_gridStep; // draw virtical grid lines for (qreal x = startV; x < rect.right();) { x += m_gridStep; painter->drawPoint(x, y); } } break; } default: { painter->fillRect(rect, ColorBlack); break; } } } else painter->fillRect(rect, ColorBlack); }
/*! Align and draw the text label of the marker \param painter Painter \param canvasRect Contents rectangle of the canvas in painter coordinates \param pos Position of the marker, translated into widget coordinates \sa drawLabel(), QwtSymbol::drawSymbol() */ void QwtPlotMarker::drawLabel( QPainter *painter, const QRectF &canvasRect, const QPointF &pos ) const { if ( d_data->label.isEmpty() ) return; Qt::Alignment align = d_data->labelAlignment; QPointF alignPos = pos; QSizeF symbolOff( 0, 0 ); switch ( d_data->style ) { case QwtPlotMarker::VLine: { // In VLine-style the y-position is pointless and // the alignment flags are relative to the canvas if ( d_data->labelAlignment & Qt::AlignTop ) { alignPos.setY( canvasRect.top() ); align &= ~Qt::AlignTop; align |= Qt::AlignBottom; } else if ( d_data->labelAlignment & Qt::AlignBottom ) { // In HLine-style the x-position is pointless and // the alignment flags are relative to the canvas alignPos.setY( canvasRect.bottom() - 1 ); align &= ~Qt::AlignBottom; align |= Qt::AlignTop; } else { alignPos.setY( canvasRect.center().y() ); } break; } case QwtPlotMarker::HLine: { if ( d_data->labelAlignment & Qt::AlignLeft ) { alignPos.setX( canvasRect.left() ); align &= ~Qt::AlignLeft; align |= Qt::AlignRight; } else if ( d_data->labelAlignment & Qt::AlignRight ) { alignPos.setX( canvasRect.right() - 1 ); align &= ~Qt::AlignRight; align |= Qt::AlignLeft; } else { alignPos.setX( canvasRect.center().x() ); } break; } default: { if ( d_data->symbol && ( d_data->symbol->style() != QwtSymbol::NoSymbol ) ) { symbolOff = d_data->symbol->size() + QSizeF( 1, 1 ); symbolOff /= 2; } } } qreal pw2 = d_data->pen.widthF() / 2.0; if ( pw2 == 0.0 ) pw2 = 0.5; const int spacing = d_data->spacing; const qreal xOff = qMax( pw2, symbolOff.width() ); const qreal yOff = qMax( pw2, symbolOff.height() ); const QSizeF textSize = d_data->label.textSize( painter->font() ); if ( align & Qt::AlignLeft ) { alignPos.rx() -= xOff + spacing; if ( d_data->labelOrientation == Qt::Vertical ) alignPos.rx() -= textSize.height(); else alignPos.rx() -= textSize.width(); } else if ( align & Qt::AlignRight ) { alignPos.rx() += xOff + spacing; } else { if ( d_data->labelOrientation == Qt::Vertical ) alignPos.rx() -= textSize.height() / 2; else alignPos.rx() -= textSize.width() / 2; } if ( align & Qt::AlignTop ) { alignPos.ry() -= yOff + spacing; if ( d_data->labelOrientation != Qt::Vertical ) alignPos.ry() -= textSize.height(); } else if ( align & Qt::AlignBottom ) { alignPos.ry() += yOff + spacing; if ( d_data->labelOrientation == Qt::Vertical ) alignPos.ry() += textSize.width(); } else { if ( d_data->labelOrientation == Qt::Vertical ) alignPos.ry() += textSize.width() / 2; else alignPos.ry() -= textSize.height() / 2; } painter->translate( alignPos.x(), alignPos.y() ); if ( d_data->labelOrientation == Qt::Vertical ) painter->rotate( -90.0 ); const QRectF textRect( 0, 0, textSize.width(), textSize.height() ); d_data->label.draw( painter, textRect ); }
void SchemaView::configureObject(void) { Schema *schema=dynamic_cast<Schema *>(this->getSourceObject()); this->fetchChildren(); /* Only configures the schema view if the rectangle is visible and there are children objects. Otherwise the schema view is hidden */ if(schema->isRectVisible() && !children.isEmpty()) { QColor color; QRectF rect; QFont font; float sp_h=0, sp_v=0, txt_h=0; float x1=1000000, y1=1000000, x2=-1000000, y2=-1000000, width=0; QList<BaseObjectView *>::Iterator itr=children.begin(); //Configures the bounding rect based upon the children dimension while(itr!=children.end()) { rect.setTopLeft((*itr)->pos()); rect.setSize((*itr)->boundingRect().size()); if(rect.left() < x1) x1 = rect.left(); if(rect.right() > x2) x2 = rect.right(); if(rect.top() < y1) y1 = rect.top(); if(rect.bottom() > y2) y2 = rect.bottom(); itr++; } //Configures the schema name at the top sch_name->setText(/*Utf8String::create(*/schema->getName()); font=BaseObjectView::getFontStyle(ParsersAttributes::GLOBAL).font(); font.setItalic(true); font.setBold(true); font.setPointSizeF(font.pointSizeF() * 1.3f); sch_name->setFont(font); sch_name->setPos(HORIZ_SPACING, VERT_SPACING); txt_h=sch_name->boundingRect().height() + (2 * VERT_SPACING); //Configures the box with the points calculated above sp_h=(3 * HORIZ_SPACING); sp_v=(3 * VERT_SPACING) + txt_h; width=(x2-x1) + 1; if(width < sch_name->boundingRect().width()) width=sch_name->boundingRect().width(); rect.setTopLeft(QPointF(-sp_h, 0)); rect.setTopRight(QPointF(width + sp_h, 0)); rect.setBottomRight(QPointF(width + sp_h, y2-y1 + sp_v)); rect.setBottomLeft(QPointF(-sp_h, y2-y1 + sp_v)); box->setRect(rect); //Sets the schema view position this->setFlag(ItemSendsGeometryChanges, false); this->moveBy(-this->pos().x(),-this->pos().y()); this->setPos(QPointF(x1, y1 - txt_h)); schema->setPosition(this->mapToScene(rect.topLeft())); this->setFlag(ItemSendsGeometryChanges, true); color=schema->getFillColor(); color.setAlpha(80); box->setBrush(color); color=QColor(color.red()/3,color.green()/3,color.blue()/3, 80); box->setPen(QPen(color, 1, Qt::DashLine)); this->bounding_rect=rect; this->setVisible(true); this->setToolTip(/*Utf8String::create(*/schema->getName(true) + QString(" (") + schema->getTypeName() + QString(")")); sch_name->setToolTip(this->toolTip()); this->protected_icon->setPos(QPointF( sch_name->boundingRect().width() + sp_h, sch_name->pos().y() + VERT_SPACING )); this->configureObjectSelection(); this->configureProtectedIcon(); this->configurePositionInfo(this->pos()); this->configureSQLDisabledInfo(); } else this->setVisible(false); }
static QRectF scaled(const QRectF &rect, qreal factor) { return QRectF(QPointF(rect.left() * factor, rect.top() * factor), QSizeF(rect.width() * factor, rect.height() * factor)); }
void renderCode128(OROPage * page, const QRectF & r, const QString & _str, ORBarcodeData * bc) { QVector<int> str; int i = 0; // create the list.. if the list is empty then just set a start code and move on if(_str.isEmpty()) str.push_back(104); else { int rank_a = 0; int rank_b = 0; int rank_c = 0; QChar c; for(i = 0; i < _str.length(); i++) { c = _str.at(i); rank_a += (code128Index(c, SETA) != -1 ? 1 : 0); rank_b += (code128Index(c, SETB) != -1 ? 1 : 0); rank_c += (c >= '0' && c <= '9' ? 1 : 0); } if(rank_c == _str.length() && ((rank_c % 2) == 0 || rank_c > 4)) { // every value in the is a digit so we are going to go with mode C // and we have an even number or we have more than 4 values i = 0; if((rank_c % 2) == 1) { str.push_back(104); // START B c = _str.at(0); str.push_back(code128Index(c, SETB)); str.push_back(99); // MODE C i = 1; } else str.push_back(105); // START C for(i = i; i < _str.length(); i+=2) { char a, b; c = _str.at(i); a = c.toAscii(); a -= 48; c = _str.at(i+1); b = c.toAscii(); b -= 48; str.push_back(int((a * 10) + b)); } } else { // start in the mode that had the higher number of hits and then // just shift into the opposite mode as needed int set = ( rank_a > rank_b ? SETA : SETB ); str.push_back(( rank_a > rank_b ? 103 : 104 )); int v = -1; for(i = 0; i < _str.length(); i++) { c = _str.at(i); v = code128Index(c, set); if(v == -1) { v = code128Index(c, (set == SETA ? SETB : SETA)); if(v != -1) { str.push_back(98); // SHIFT str.push_back(v); } } else str.push_back(v); } } } // calculate and append the checksum value to the list int checksum = str.at(0); for(i = 1; i < str.size(); i++) checksum += (str.at(i) * i); checksum = checksum % 103; str.push_back(checksum); // lets determine some core attributes about this barcode qreal bar_width = bc->narrowBarWidth; // this is are mandatory minimum quiet zone qreal quiet_zone = bar_width * 10; if(quiet_zone < 0.1) quiet_zone = 0.1; // what kind of area do we have to work with qreal draw_width = r.width(); qreal draw_height = r.height(); // how long is the value we need to encode? int val_length = str.size() - 2; // we include start and checksum in are list so // subtract them out for our calculations // L = (11C + 35)X // L length of barcode (excluding quite zone) in units same as X and I // C the number of characters in the value excluding the start/stop and checksum characters // X the width of a bar (pixels in our case) qreal L; qreal C = val_length; qreal X = bar_width; L = (((11.0 * C) + 35.0) * X); // now we have the actual width the barcode will be so can determine the actual // size of the quiet zone (we assume we center the barcode in the given area // what should we do if the area is too small???? // At the moment the way the code is written is we will always start at the minimum // required quiet zone if we don't have enough space.... I guess we'll just have over-run // to the right // // calculate the starting position based on the alignment option // for left align we don't need to do anything as the values are already setup for it if(bc->align == 1) // center { qreal nqz = (draw_width - L) / 2.0; if(nqz > quiet_zone) quiet_zone = nqz; } else if(bc->align > 1) // right quiet_zone = draw_width - (L + quiet_zone); // else if(align < 1) {} // left : do nothing qreal pos = r.left() + quiet_zone; qreal top = r.top(); QPen pen(Qt::NoPen); QBrush brush(QColor("black")); bool space = false; int idx = 0, b = 0; qreal w = 0.0; for(i = 0; i < str.size(); i++) { // loop through each value and render the barcode idx = str.at(i); if(idx < 0 || idx > 105) { qDebug("Encountered a non-compliant element while rendering a 3of9 barcode -- skipping"); continue; } space = false; for(b = 0; b < 6; b++, space = !space) { w = _128codes[idx].values[b] * bar_width; if(!space) { ORORect * rect = new ORORect(bc); rect->setPen(pen); rect->setBrush(brush); rect->setRect(QRectF(pos,top, w,draw_height)); page->addPrimitive(rect); } pos += w; } } // we have to do the stop character seperatly like this because it has // 7 elements in it's bar sequence rather than 6 like the others int STOP_CHARACTER[]={ 2, 3, 3, 1, 1, 1, 2 }; space = false; for(b = 0; b < 7; b++, space = !space) { w = STOP_CHARACTER[b] * bar_width; if(!space) { ORORect * rect = new ORORect(bc); rect->setPen(pen); rect->setBrush(brush); rect->setRect(QRectF(pos,top, w,draw_height)); page->addPrimitive(rect); } pos += w; } return; }
/*! Draw a color bar into a rectangle \param painter Painter \param colorMap Color map \param interval Value range \param scaleMap Scale map \param orientation Orientation \param rect Traget rectangle */ void QwtPainter::drawColorBar( QPainter *painter, const QwtColorMap &colorMap, const QwtInterval &interval, const QwtScaleMap &scaleMap, Qt::Orientation orientation, const QRectF &rect ) { QVector<QRgb> colorTable; if ( colorMap.format() == QwtColorMap::Indexed ) colorTable = colorMap.colorTable( interval ); QColor c; const QRect devRect = rect.toAlignedRect(); /* We paint to a pixmap first to have something scalable for printing ( f.e. in a Pdf document ) */ QPixmap pixmap( devRect.size() ); QPainter pmPainter( &pixmap ); pmPainter.translate( -devRect.x(), -devRect.y() ); if ( orientation == Qt::Horizontal ) { QwtScaleMap sMap = scaleMap; sMap.setPaintInterval( rect.left(), rect.right() ); for ( int x = devRect.left(); x <= devRect.right(); x++ ) { const double value = sMap.invTransform( x ); if ( colorMap.format() == QwtColorMap::RGB ) c.setRgba( colorMap.rgb( interval, value ) ); else c = colorTable[colorMap.colorIndex( interval, value )]; pmPainter.setPen( c ); pmPainter.drawLine( x, devRect.top(), x, devRect.bottom() ); } } else // Vertical { QwtScaleMap sMap = scaleMap; sMap.setPaintInterval( rect.bottom(), rect.top() ); for ( int y = devRect.top(); y <= devRect.bottom(); y++ ) { const double value = sMap.invTransform( y ); if ( colorMap.format() == QwtColorMap::RGB ) c.setRgb( colorMap.rgb( interval, value ) ); else c = colorTable[colorMap.colorIndex( interval, value )]; pmPainter.setPen( c ); pmPainter.drawLine( devRect.left(), y, devRect.right(), y ); } } pmPainter.end(); drawPixmap( painter, rect, pixmap ); }
void renderCodeUPCA(OROPage * page, const QRectF & r, const QString & _str, ORBarcodeData * bc) { int val[13]; int i = 0; // initialize all the values just so we can be predictable for(i = 0; i < 13; i++) val[i] = -1; // verify that the passed in string is valid // if it's not either twelve or thirteen characters // then it must be invalid to begin with if(_str.length() != 11 && _str.length() != 12) return; // loop through and convert each char to a digit. // if we can't convert all characters then this is // an invalid number val[0] = 0; for(i = 0; i < _str.length(); i++) { val[i+1] = ((QChar)_str.at(i)).digitValue(); if(val[i+1] == -1) return; } // calculate and append the checksum value int old_sum = val[12]; // get the old check sum value (-1 if none was set) int checksum = 0; for(i = 0; i < 12; i++) checksum += val[i] * (i % 2 ? 3 : 1); checksum = (checksum % 10); if(checksum) checksum = 10 - checksum; val[12] = checksum; // if we had an old checksum value and if it doesn't match what we came // up with then the string must be invalid so we will bail if(old_sum != -1 && old_sum != checksum) return; // lets determine some core attributes about this barcode qreal bar_width = bc->narrowBarWidth; // the width of the base unit bar // this is are mandatory minimum quiet zone qreal quiet_zone = bar_width * 10; if(quiet_zone < 0.1) quiet_zone = 0.1; // what kind of area do we have to work with qreal draw_width = r.width(); qreal draw_height = r.height() - 0.02; // L = 95X // L length of barcode (excluding quite zone) in units same as X and I // X the width of a bar (pixels in our case) qreal L; qreal X = bar_width; L = (95.0 * X); // now we have the actual width the barcode will be so can determine the actual // size of the quiet zone (we assume we center the barcode in the given area // what should we do if the area is too small???? // At the moment the way the code is written is we will always start at the minimum // required quiet zone if we don't have enough space.... I guess we'll just have over-run // to the right // // calculate the starting position based on the alignment option // for left align we don't need to do anything as the values are already setup for it if(bc->align == 1) // center { qreal nqz = (draw_width - L) / 2; if(nqz > quiet_zone) quiet_zone = nqz; } else if(bc->align > 1) // right quiet_zone = draw_width - (L + quiet_zone); // else if(align < 1) {} // left : do nothing qreal pos = r.left() + quiet_zone; qreal top = r.top(); QPen pen(Qt::NoPen); QBrush brush(QColor("black")); int b = 0; int w = 0; // render open guard ORORect * rect = new ORORect(bc); rect->setPen(pen); rect->setBrush(brush); rect->setRect(QRectF(pos,top, bar_width,draw_height)); rect->setRotationAxis(r.topLeft()); page->addPrimitive(rect); pos += (bar_width * 2.0); rect = new ORORect(bc); rect->setPen(pen); rect->setBrush(brush); rect->setRect(QRectF(pos,top, bar_width,draw_height)); rect->setRotationAxis(r.topLeft()); page->addPrimitive(rect); pos += bar_width; // render first set for(i = 0; i < 6; i++) { b = val[i+1]; for(w = 0; w < 7; w++) { if(_encodings[b][_parity[val[0]][i]][w]) { rect = new ORORect(bc); rect->setPen(pen); rect->setBrush(brush); rect->setRect(QRectF(pos,top, bar_width,draw_height - (i==0?0:0.07))); rect->setRotationAxis(r.topLeft()); page->addPrimitive(rect); } pos += bar_width; } } // render center guard pos += bar_width; rect = new ORORect(bc); rect->setPen(pen); rect->setBrush(brush); rect->setRect(QRectF(pos,top, bar_width,draw_height)); rect->setRotationAxis(r.topLeft()); page->addPrimitive(rect); pos += (bar_width * 2.0); rect = new ORORect(bc); rect->setPen(pen); rect->setBrush(brush); rect->setRect(QRectF(pos,top, bar_width,draw_height)); rect->setRotationAxis(r.topLeft()); page->addPrimitive(rect); pos += (bar_width * 2.0); // render last set for(i = 0; i < 6; i++) { b = val[i+7]; for(w = 0; w < 7; w++) { if(_encodings[b][RIGHTHAND][w]) { rect = new ORORect(bc); rect->setPen(pen); rect->setBrush(brush); rect->setRect(QRectF(pos,top, bar_width,draw_height - (i==5?0:0.07))); rect->setRotationAxis(r.topLeft()); page->addPrimitive(rect); } pos += bar_width; } } // render close guard rect = new ORORect(bc); rect->setPen(pen); rect->setBrush(brush); rect->setRect(QRectF(pos,top, bar_width,draw_height)); rect->setRotationAxis(r.topLeft()); page->addPrimitive(rect); pos += (bar_width * 2.0); rect = new ORORect(bc); rect->setPen(pen); rect->setBrush(brush); rect->setRect(QRectF(pos,top, bar_width,draw_height)); rect->setRotationAxis(r.topLeft()); page->addPrimitive(rect); QString parstr = QString("%1").arg(val[1]); QString chkstr = QString("%1").arg(val[12]); QString leftstr = QString().sprintf("%d%d%d%d%d", val[2], val[3], val[4], val[5], val[6]); QString rightstr = QString().sprintf("%d%d%d%d%d", val[7], val[8], val[9], val[10], val[11]); QFont font("Arial",6); OROTextBox * tb = new OROTextBox(bc); tb->setPosition(QPointF(r.left(), r.top() + draw_height - 0.12)); tb->setSize(QSizeF(quiet_zone - 0.02, 0.12)); tb->setFont(font); tb->setText(parstr); tb->setFlags(Qt::AlignRight | Qt::AlignTop); rect->setRotationAxis(r.topLeft()); page->addPrimitive(tb); tb = new OROTextBox(bc); tb->setPosition(QPointF(r.left() + quiet_zone + 0.10, (r.top() + draw_height) - 0.07)); tb->setSize(QSizeF(0.35, 0.10)); tb->setFont(font); tb->setText(leftstr); tb->setFlags(Qt::AlignHCenter | Qt::AlignTop); rect->setRotationAxis(r.topLeft()); page->addPrimitive(tb); tb = new OROTextBox(bc); tb->setPosition(QPointF(r.left() + quiet_zone + 0.50, (r.top() + draw_height) - 0.07)); tb->setSize(QSizeF(0.35, 0.10)); tb->setFont(font); tb->setText(rightstr); tb->setFlags(Qt::AlignHCenter | Qt::AlignTop); rect->setRotationAxis(r.topLeft()); page->addPrimitive(tb); tb = new OROTextBox(bc); tb->setPosition(QPointF(r.left() + quiet_zone + L + 0.02, (r.top() + draw_height) - 0.12)); tb->setSize(QSizeF(0.08, 0.12)); tb->setFont(font); tb->setText(chkstr); tb->setFlags(Qt::AlignLeft | Qt::AlignTop); rect->setRotationAxis(r.topLeft()); page->addPrimitive(tb); return; }
//! //! Updates the path end points according to the positions of start and end //! nodes. //! void ConnectionGraphicsItem::updatePath () { prepareGeometryChange(); // calculate positions of the end points QPointF startPoint = m_startPoint; QPointF endPoint = m_endPoint; if (m_startNodeItem) startPoint += m_startNodeItem->pos(); if (m_endNodeItem) endPoint += m_endNodeItem->pos(); // calculate the rectangles to help calculating the positions of the node's anchor points const qreal offset = 10; QRectF baseAnchorRect = QRectF(-offset, -offset, 2 * offset, 2 * offset); QRectF startAnchorRect = baseAnchorRect.translated(startPoint); QRectF endAnchorRect = baseAnchorRect.translated(endPoint); if (m_startNodeItem) startAnchorRect = m_startNodeItem->rect().adjusted(-offset, -offset, offset, offset).translated(m_startNodeItem->pos()); if (m_endNodeItem) endAnchorRect = m_endNodeItem->rect().adjusted(-offset, -offset, offset, offset).translated(m_endNodeItem->pos()); // // Diagram of anchor points for start and end nodes: // // x x sU2, sU1 eU1, eU2 x x // ,----, ,----, // | | | | // | | | | // | x| x sP, sO eO, eP x |x | // '----' '----' // x x sL2, sL1 eL1, eL2 x x // QPointF sP = startPoint; QPointF sO = QPointF(startAnchorRect.right(), startPoint.y()); QPointF sU1 = startAnchorRect.topRight(); QPointF sU2 = startAnchorRect.topLeft(); QPointF sL1 = startAnchorRect.bottomRight(); QPointF sL2 = startAnchorRect.bottomLeft(); QPointF eP = endPoint; QPointF eO = QPointF(endAnchorRect.left(), endPoint.y()); QPointF eU1 = endAnchorRect.topLeft(); QPointF eU2 = endAnchorRect.topRight(); QPointF eL1 = endAnchorRect.bottomLeft(); QPointF eL2 = endAnchorRect.bottomRight(); // declare path segments QList<QPointF> startPoints; QPainterPath cubicPath; QList<QPointF> endPoints; // construct the path segments if (eO.x() < sO.x() && eU2.x() > sL2.x() && eU2.y() < sL2.y() && eL2.y() > sU2.y()) { //> case 1V: elements very close to each other startPoints << sP << sO; QPointF offsetVector = QPointF(0, 0.75 * (eO.y() - sO.y())); cubicPath.moveTo(sO); cubicPath.cubicTo(sO + offsetVector, eO - offsetVector, eO); endPoints << eO << eP; } else if (eO.x() >= sO.x()) { //> case 1H: end node is right of start node startPoints << sP << sO; QPointF offsetVector = QPointF(0.75 * (eO.x() - sO.x()), 0); cubicPath.moveTo(sO); cubicPath.cubicTo(sO + offsetVector, eO - offsetVector, eO); endPoints << eO << eP; } else if (eU1.y() >= sL1.y()) { //> case 2LV startPoints << sP << sO << sL1; QPointF offsetVector = QPointF(0, 0.75 * (eU1.y() - sL1.y())); cubicPath.moveTo(sL1); cubicPath.cubicTo(sL1 + offsetVector, eU1 - offsetVector, eU1); endPoints << eU1 << eO << eP; } else if (eL1.y() <= sU1.y()) { //> case 2UV startPoints << sP << sO << sU1; QPointF offsetVector = QPointF(0, 0.75 * (eL1.y() - sU1.y())); cubicPath.moveTo(sU1); cubicPath.cubicTo(sU1 + offsetVector, eL1 - offsetVector, eL1); endPoints << eL1 << eO << eP; } else if (eP.y() >= sP.y()) { //> case 3L startPoints << sP << sO << sL1 << sL2; QPointF offsetVector = QPointF(0.75 * (eU2.x() - sL2.x()), 0); cubicPath.moveTo(sL2); cubicPath.cubicTo(sL2 + offsetVector, eU2 - offsetVector, eU2); endPoints << eU2 << eU1 << eO << eP; } else { //> case 3U startPoints << sP << sO << sU1 << sU2; QPointF offsetVector = QPointF(0.75 * (eL2.x() - sU2.x()), 0); cubicPath.moveTo(sU2); cubicPath.cubicTo(sU2 + offsetVector, eL2 - offsetVector, eL2); endPoints << eL2 << eL1 << eO << eP; } // build the main path from the path segments m_mainPath = QPainterPath(); for (int i = 0; i < startPoints.size(); ++i) if (i == 0) m_mainPath.moveTo(startPoints[0]); else m_mainPath.lineTo(startPoints[i]); m_mainPath.addPath(cubicPath); for (int i = 0; i < endPoints.size(); ++i) if (i == 0) m_mainPath.moveTo(endPoints[0]); else m_mainPath.lineTo(endPoints[i]); // create the shadow path as a copy of the main path m_shadowPath = QPainterPath(m_mainPath); // move the path elements of the shadow path one pixel down and to the right for (int i = 1; i < m_shadowPath.elementCount(); ++i) { QPainterPath::Element element = m_shadowPath.elementAt(i); m_shadowPath.setElementPositionAt(i, element.x + 1, element.y + 1); } // get the center point for the arrow and the angle at that point static const qreal t = 0.5; QPointF arrowPoint = cubicPath.pointAtPercent(t); qreal angle = cubicPath.angleAtPercent(t) * Pi / 180; // calculate the polygon for the arrow head qreal pathLengthFraction = m_mainPath.length() / 10; static const qreal maxArrowSize = 10; qreal arrowSize = pathLengthFraction < maxArrowSize ? pathLengthFraction : maxArrowSize; QPointF arrowPoint1 = arrowPoint - QPointF(arrowSize * sin(angle - Pi / 2), arrowSize * cos(angle - Pi / 2)); QPointF arrowPoint2 = arrowPoint - QPointF(arrowSize * sin(angle + Pi / 3), arrowSize * cos(angle + Pi / 3)); QPointF arrowPoint3 = arrowPoint - QPointF(arrowSize * sin(angle + Pi - Pi / 3), arrowSize * cos(angle + Pi - Pi / 3)); m_arrowHeadPolygon.clear(); m_arrowHeadPolygon << arrowPoint1 << arrowPoint2 << arrowPoint3; // repaint the graphics item update(); }