QLineF Robot::intersectDistance(QGraphicsLineItem *item, const double &baseAngle) const { QGraphicsScene *scene = item->scene(); if(!scene) return QLineF(0, 0, 0, 0); const double rad = (m_robot->rotation() + baseAngle) / 180.0 * M_PI; QLineF line(m_robot->pos(), m_robot->pos() + m_rangeLength * QPointF(cos(rad), sin(rad))); const QLineF unit = line.unitVector(); // qDebug() << unit.dx(); double xs = unit.dx(); double ys = unit.dy(); if(xs == 0.0) xs = 0.0001; if(ys == 0.0) ys = 0.0001; for(double i = 0; i < m_rangeLength; i += 1.0) { QRectF r(m_robot->x() + i * xs, m_robot->y() + i * ys, xs, ys); QList<QGraphicsItem *> items = scene->items(r, Qt::IntersectsItemBoundingRect, Qt::AscendingOrder); foreach(QGraphicsItem *t, items) { if(t->data(0) == BoardFile::Real) { line.setLength(i); return line; } } } return line; }
QPointF EdgeSnapper::snap(const QPointF& pos) { QGraphicsScene* scene = theView->scene(); // TODO: probably should use the view to get the items so that // the same visible area is always used for item selection, independent // of view transformation QList<QGraphicsItem *> items = scene->items (QRectF(pos.x() - 4, pos.y() - 4, 8, 8), Qt::IntersectsItemShape); qreal minDist = 4.0; // minimum distance QPointF result = pos; bool found = false; //qDebug() << "Items: " << items.size() - 1; foreach(QGraphicsItem* item, items) { InteractableItem* iItem = dynamic_cast<InteractableItem*>(item); if (iItem && iItem != theView->getFocusItem()) { // TODO: Better approach to filter out current item? QPointF edge = iItem->getNearestEdge(theView, pos); qreal dist = sqrt(pow(pos.x() - edge.x(), 2) + pow(pos.y() - edge.y(), 2)); if (dist < minDist) { found = true; minDist = dist; result = edge; } } }
double Robot::reflectanceReading(double sensorX, double sensorY) { double result = 0.0; double weight = 1.0 / num_pts; double spiral_scale = 2.0; QGraphicsScene *scene = m_leftRange->scene(); for (int i = 0; i < num_pts; i++){ double spiralX = spiral_xs[i]*spiral_scale + sensorX; double spiralY = spiral_ys[i]*spiral_scale + sensorY; QRectF r(QPoint(spiralX, spiralY), QSize(1,1)); QList<QGraphicsItem *> items = scene->items(r, Qt::IntersectsItemBoundingRect, Qt::AscendingOrder); foreach(QGraphicsItem *t, items) { if(t->data(0) == BoardFile::Tape) { result += weight; continue; } } } return result; }
void GraphWidget::draw(ITree<GuiNode>* tree) { //Reset properties (only usefull when drawing more than one tree) resetCachedContent(); resetMatrix(); resetTransform(); //Set Properties setCacheMode(CacheBackground); setViewportUpdateMode(QGraphicsView::FullViewportUpdate); setTransformationAnchor(QGraphicsView::AnchorUnderMouse); setDragMode(QGraphicsView::ScrollHandDrag); rotate(qreal(-90)); //Create scene QGraphicsScene* scene; if (this->scene() != NULL) { scene = this->scene(); QListIterator<QGraphicsItem*> items(scene->items()); while (items.hasNext()) { scene->removeItem(items.next()); } delete scene; } scene = new QGraphicsScene(this); this->setScene(scene); this->tree = tree; drawTree(this->scene(), tree->getRoot()); //Ensure visibility of the tree this->fitInView(this->scene()->itemsBoundingRect(), Qt::KeepAspectRatio); }
void PartsEditorSketchWidget::clearScene() { QGraphicsScene * scene = this->scene(); //QList<QGraphicsItem*> items; for(int i=0; i < scene->items().size(); i++){ ItemBase * itemBase = ItemBase::extractTopLevelItemBase(scene->items()[i]); if (itemBase == NULL) { //items << scene->items()[i]; continue; } this->deleteItem(itemBase, true, true); } /*for(int i=0; i < items.size(); i++) { scene->removeItem(items[i]); }*/ }
SEXP qt_qitemsInRect_QGraphicsScene(SEXP rself, SEXP rrect) { QGraphicsScene *self = unwrapQObject(rself, QGraphicsScene); SEXP ans; QList<QGraphicsItem *> items = self->items(asQRectF(rrect)); ans = allocVector(VECSXP, items.size()); for (int i = 0; i < length(ans); i++) SET_VECTOR_ELT(ans, i, wrapQGraphicsItem(items[i])); return ans; }
bool QGModifyInteractor::normalStateFilter(QObject * obj, QEvent * evt) { // Flag indicating if the received event must be trapped by the // method (ie. not passed to other filters). bool trap = false; if (evt->type() == QEvent::MouseButtonPress) { QMouseEvent * me = dynamic_cast<QMouseEvent *>(evt); if (me->button() == Qt::LeftButton) { // -------------------------- // Left-Click: Item selection // -------------------------- //-- Look up for collisions. // Compute cursors 'real position' QPoint realPos = _view->toRealCoords( me->pos() ); // Access to the current document canvas. QGraphicsScene * canvas = _layer->canvas(); // Retrieve all objects intersecting with a square of 5 pixels edge. QRect selRect(realPos - QPoint(2, 2), realPos + QPoint(2, 2)); QList<QGraphicsItem*> itemList = canvas->items(selRect); if (!itemList.empty()) { //-- Set the selected item. // The item selected is the first item of the collision list // The item is informed that it is selected thus it can modify // its appearence. setSelectedItem(itemList.front()); //-- Change state to 'selectedItem' state // Remove current filter and install 'selectedItem' filter. _view->viewport()->removeEventFilter(_normalFilter); _view->viewport()->installEventFilter(_selectedItemFilter); // Enable keyboard event on the viewport. _view->viewport()->setFocus(); //-- Prevent the click event to be forwarded. trap = true; }// if empty() }// if leftButton }// if MouseButtonPress return trap; }
SEXP qt_qupdate_QGraphicsScene(SEXP rself) { QGraphicsScene *scene = unwrapQObject(rself, QGraphicsScene); QList<QGraphicsItem *> items = scene->items(); for (int i = 0; i < items.size(); i++) { QGraphicsItem *item = items[i]; QGraphicsItem::CacheMode mode = item->cacheMode(); item->setCacheMode(QGraphicsItem::NoCache); item->setCacheMode(mode); } scene->update(); return rself; }
GraphWidget::~GraphWidget() { QGraphicsScene* scene; if (this->scene() != NULL) { scene = this->scene(); QListIterator<QGraphicsItem*> items(scene->items()); while (items.hasNext()) { scene->removeItem(items.next()); } } }
SCgObject* IncidencePointGraphicsItem::objectAtPoint() const { QGraphicsScene* s = scene(); Q_ASSERT(s); QList<QGraphicsItem*> itemList = s->items(scenePos(), Qt::IntersectsItemShape, Qt::DescendingOrder); foreach(QGraphicsItem* it, itemList) if (it != this && it != mParent && SCgObject::isSCgObjectType(it->type())) return static_cast<SCgObject*>(it); return 0; }
void core::Connector::updateConectorLine(const QPointF &begin, const QPointF &end) { const double MIN_LENGHT = 10; // QLineF line(begin, end); QList<QGraphicsItem*> collidingItemsEndOfLine, collidingItemsMiddleLine, fullList; // QGraphicsItem *closerItem; // QRectF closerItemRect; // QPointF // correctedEnd = end, // midPoint, // mappedMidPoint; if(composedLine.isEmpty()){ Port p = beginObject->getCurrentPort(mapToItem(beginObject, begin)); RestrictedLineF *firstLine = new RestrictedLineF(begin, end); switch(p){ case GraphicObject::portBottom: firstLine->setConstrain(RestrictedLineF::VerticalDown); break; case GraphicObject::portTop: firstLine->setConstrain(RestrictedLineF::VerticalUp); break; case GraphicObject::portLeft: firstLine->setConstrain(RestrictedLineF::HorizontalLeft); break; case GraphicObject::portRight: firstLine->setConstrain(RestrictedLineF::HorizontalRight); break; case GraphicObject::portNone: default: firstLine->setConstrain(RestrictedLineF::None); break; } composedLine.push_back(firstLine); shapeForm.push_back(firstLine->p1()); shapeForm.push_back(firstLine->p2()); } QGraphicsScene *env = scene(); QList<CollidingResult> colItems = collidingObjects(composedLine); // for(int i = 0; i < colItems.size(); i++){ // colItems[i].line->setConstrain(RestrictedLineF::Both); // } RestrictedLineF temptativeLine, *curLine; for(auto i = composedLine.size()-1; i >= 0; i--){ curLine = composedLine[i]; temptativeLine = *curLine; if(i == composedLine.size() - 1){ if(env){ fullList = env->items(mapToScene(end)); collidingItemsEndOfLine = removeIgnoredObjects(fullList); if(composedLine.size() > 1){ fullList = env->items(mapToScene(composedLine[i - 1]->getCorrectedP2(end))); collidingItemsMiddleLine = removeIgnoredObjects(fullList); } if(collidingItemsEndOfLine.isEmpty() && collidingItemsMiddleLine.isEmpty()){ if(composedLine.size() > 1){ composedLine[i - 1]->setP2(end); curLine->setP1(composedLine[i - 1]->p2()); shapeForm[i] = composedLine[i - 1]->p2(); } //Set the point p2 to curLine (it will be corrected against restrictions) curLine->setP2(end); shapeForm[i + 1] = curLine->p2(); //calculates the distance between corrected p2 of curLine and current end point if(math::distance(curLine->p2(), end) >= MIN_LENGHT && !curLine->isNull() && !(i = 1 && composedLine[0]->isNull())){ RestrictedLineF::Constrain restriction; switch (curLine->getConstrain()) { case RestrictedLineF::HorizontalRight: case RestrictedLineF::HorizontalLeft: case RestrictedLineF::Horizontal: restriction = RestrictedLineF::Vertical; break; case RestrictedLineF::VerticalUp: case RestrictedLineF::VerticalDown: case RestrictedLineF::Vertical: restriction = RestrictedLineF::Horizontal; break; case RestrictedLineF::Both: if(fabs(curLine->p2().x() - end.x()) >= fabs(curLine->p2().y() - end.y())){ restriction = RestrictedLineF::Horizontal; }else{ restriction = RestrictedLineF::Vertical; } break; case RestrictedLineF::None: default: restriction = RestrictedLineF::None; break; } RestrictedLineF *newLine = new RestrictedLineF(curLine->p2(), end, restriction); composedLine.push_back(newLine); //use in case shapeForm be QPainterPath // shapeForm.lineTo(newLine->p2()); //use in case shapeForm be QPolygonF // shapeForm[i + 1] shapeForm.push_back(newLine->p2()); } } } }else if(i == composedLine.size() - 2){ } if(curLine->length() < MIN_LENGHT && i != 0){ composedLine.remove(i); shapeForm.remove(i+1); }else if(i == 1){ if(composedLine[i - 1]->isNull()){ composedLine.remove(i); shapeForm.remove(i+1); } } } // shapeForm = QPainterPath(begin); //// shapeForm // for(auto i = 0; i < composedLine.size(); i++){ // shapeForm.lineTo(composedLine[i]->p2()); // } // //Only for debug process. Can be simplified // midPoint = QPointF(end.x(), 0); // mappedMidPoint = mapToScene(midPoint); // fullList = collidingItems(Qt::IntersectsItemShape); // itemListAt = removeIgnoredObjects(fullList); // if(fabs(line.dx()) >= fabs(line.dy())){ // if(itemListAt.size() > 0){ // if(midPoint.x() >= 0){ // closerItem = closerItemPerif(midPoint, portLeft, itemListAt); // closerItemRect = mapFromItem(closerItem, closerItem->boundingRect()).boundingRect(); // midPoint.setX(closerItemRect.left()/* - clearance*/); // correctedEnd.setX(closerItemRect.left()); // }else{ // closerItem = closerItemPerif(midPoint, portRight, itemListAt); // closerItemRect = mapFromItem(closerItem, closerItem->boundingRect()).boundingRect(); // midPoint.setX(closerItemRect.right()/* + clearance*/); // correctedEnd.setX(closerItemRect.right()); // } // } //// composedLine.push_back(QLineF(begin, midPoint)); //// composedLine.push_back(QLineF(midPoint, correctedEnd)); // }else{ // if(itemListAt.size() > 0){ // if(midPoint.y() >= 0){ // closerItem = closerItemPerif(midPoint, portTop, itemListAt); // closerItemRect = mapFromItem(closerItem, closerItem->boundingRect()).boundingRect(); // midPoint.setY(closerItemRect.top()/* - clearance*/); // correctedEnd.setY(closerItemRect.top()); // }else{ // closerItem = closerItemPerif(midPoint, portBottom, itemListAt); // closerItemRect = mapFromItem(closerItem, closerItem->boundingRect()).boundingRect(); // midPoint.setY(closerItemRect.bottom()/* + clearance*/); // correctedEnd.setY(closerItemRect.bottom()); // } // } // } // composedLine.clear(); // composedLine.push_back(QLineF(begin, midPoint)); // composedLine.push_back(QLineF(midPoint, correctedEnd)); }
bool QtPrinterTableView::print() { Q_D(QtPrinterTableView); if (! d->printer->isValid()) { qWarning() << "QtPrinterTableView::print: printer not valid, please setup the printer before calling print"; return false; } // next use a view just for the filling of the options... QGraphicsScene scene; QtGraphicsTableView view; scene.addItem(&view); view.setModel(d->model); class QTableHeaderDataProvider2 : public QtGraphicsHeaderDataProvider { public: QTableHeaderDataProvider2(QtTableModelInterface *model_) : model(model_) {} QHash<int,QVariant> data(int logicalIndex, const QList<int> &roles) const { // ### call the model - temporary implementation QHash<int,QVariant> hash; for (int i = 0; i < roles.count(); ++i) if (roles.at(i) == Qt::DisplayRole) hash.insert(Qt::DisplayRole, logicalIndex + 1); return hash; } QtTableModelInterface *model; }; if (d->horizontalHeader) { QtGraphicsHeader *header = new QtGraphicsHeader(Qt::Horizontal, &view); header->setDataProvider(new QTableHeaderDataProvider2(d->model)); header->copySections(*d->horizontalHeader); view.setHorizontalHeader(header); } if (d->verticalHeader) { QtGraphicsHeader *header = new QtGraphicsHeader(Qt::Vertical, &view); header->setDataProvider(new QTableHeaderDataProvider2(d->model)); header->copySections(*d->verticalHeader); view.setVerticalHeader(header); } QPainter painter; if (!painter.begin(d->printer)) { qWarning() << "QtPrinterTableView::print: printer fails to begin(), sorry can't print"; return false; } // re-layout the header footer to the current page size. if (d->header) { d->header->documentLayout()->setPaintDevice(d->printer); d->header->setPageSize(d->printer->pageRect().size()); } if (d->footer) { d->footer->documentLayout()->setPaintDevice(d->printer); d->footer->setPageSize(d->printer->pageRect().size()); } const qreal headerSize = d->printHeader(painter); const qreal footerSize = d->printFooter(painter); const bool vertical = d->orientation == Qt::Vertical; const qreal scaleX = d->printer->logicalDpiX() / (qreal) qt_defaultDpiX(); const qreal scaleY = d->printer->logicalDpiY() / (qreal) qt_defaultDpiY(); painter.scale(scaleX, scaleY); const QRect rect = d->printer->pageRect(); QSizeF visibleSize(rect.width() / scaleX, rect.height() / scaleY); if (vertical) visibleSize = QSizeF(visibleSize.width(), visibleSize.height() - headerSize - footerSize); else // then rotate it. visibleSize = QSizeF(visibleSize.height() - headerSize - footerSize, visibleSize.width()); view.setGeometry(0, 0, visibleSize.width(), visibleSize.height()); view.setHorizontalOffset(0); int row = 0; int column; bool first = true; qreal offsetInColumn = 0; // for those columns too wide and thus split over more than one page while (row < d->model->rowCount()) { column = 0; view.setFirstRow(row); qreal height = visibleSize.height(); while (true) { const qreal rowHeight = view.rowHeight(row); if (height - rowHeight < 0) break; if (row >= d->model->rowCount()) break; ++row; height -= rowHeight; } while (column < d->model->columnCount()) { if (!first) { d->printer->newPage(); d->printHeader(painter); d->printFooter(painter); } first = false; view.setFirstColumn(column); view.setHorizontalOffset(offsetInColumn); qreal width = visibleSize.width(); while (true) { const qreal columnWidth = view.columnWidth(column); if (width == visibleSize.width() && columnWidth - offsetInColumn > visibleSize.width()) { // the column doesn't fit on a page. Lets split it. offsetInColumn += visibleSize.width(); width = 0; break; } else if (offsetInColumn > 0) { // we still have a part of a split column to print! width -= columnWidth - offsetInColumn; offsetInColumn = 0; ++column; continue; } if (width - columnWidth + offsetInColumn < 0) break; if (column >= d->model->columnCount()) break; ++column; width -= columnWidth; } view.doLayout(); painter.save(); // for each page painter.translate(0, headerSize); if (!vertical) { painter.translate(0, visibleSize.width()); painter.rotate(-90); } #ifdef DEBUG_TABLES painter.setPen(QPen(QColor(Qt::green))); painter.drawRect(QRectF(0, 0, visibleSize.width() - width, visibleSize.height() - height)); #endif painter.setClipRect(QRectF(0, 0, visibleSize.width() - width, visibleSize.height() - height)); // find and paint children which are the cells QList<QGraphicsItem*> items = scene.items(view.rect()); QList<QGraphicsItem*>::Iterator iter = items.begin(); for (;iter != items.end(); ++iter) { QGraphicsItem *parent = *iter; while (parent != &view && parent != 0) // only draw children of our view parent = parent->parentItem(); if (parent == 0) continue; if (!(*iter)->isVisible()) continue; painter.save(); painter.translate((*iter)->mapToItem(&view, QPointF())); #ifdef DEBUG_TABLES QGraphicsWidget *w = dynamic_cast<QGraphicsWidget*>(*iter); if (w) { painter.save(); painter.setPen(QPen(QColor(Qt::red))); painter.drawRect(QRectF(QPointF(), w->size())); painter.restore(); } #endif (*iter)->paint(&painter, 0); painter.restore(); } painter.restore(); // for each page } } return true; }
//virtual void VirtualCamera::setup(const QGraphicsItem * farBoundItem,const QList<QPointer<ThingPaintable> >& exclusionList, const QRectF& sceneViewport) { m_triggerAble = false; //grab the scene pointer, or bail if not available QGraphicsScene * pScene = DimensionsGlobal::globalGraphicsScene(); if (!pScene) { qDebug() << __FUNCTION__ << ": global graphics scene not available"; return; } QList<QGraphicsItem *> rawItems; QSize rectSize; //if the sceneViewport isn't empty, then just get the items that are w/in it // use Qt::IntersectsItemBoundingRect to speed things up; this doesn't have to be exact, since the actual render by // trigger() will have to deal with source regions anyways if (!sceneViewport.isEmpty()) { rectSize = sceneViewport.size().toSize(); if ((rectSize.width() == 0) || (rectSize.height() == 0)) { //would cause problems later m_viewport = QRectF(); return; } m_viewport = sceneViewport; rawItems = pScene->items(sceneViewport,Qt::IntersectsItemBoundingRect,Qt::AscendingOrder); //SHOULD be ok to convert toSize(), w.r.t. trunc-ing off decimal bits and getting a smaller whole size // painter will have to do a similar thing so it SHOULD be compatible. // if things crash, look here first! } else //else get everything { rectSize = pScene->sceneRect().size().toSize(); if ((rectSize.width() == 0) || (rectSize.height() == 0)) { m_viewport = QRectF(); return; } m_viewport = pScene->sceneRect(); rawItems = pScene->items(pScene->sceneRect(),Qt::IntersectsItemBoundingRect,Qt::AscendingOrder); } //re-init the excludes m_excludes = QSet<QPointer<ThingPaintable> >::fromList(exclusionList); //clear the subjects m_subjects.clear(); //the list is in ascending stack order. Toss out anything: // 1. below the farBoundItem // 2. not a ThingPaintable // 3. in the exclusion list //can't directly use "visible" as a determinant; the scene *can* provide an indicator of whether or not an item is occluded. // However, tossing out items by 1,2,3, above may actually reveal an item that was previously occluded, so more complicated logic // would be needed. It's ok though. The likelihood of it giving a significant reduction is minimal against the expense to // determine it. bool farItemReached = (farBoundItem == 0 ? true : false); //if no far item was specified then set as already reached for (QList<QGraphicsItem *>::iterator it = rawItems.begin(); it != rawItems.end();++it) { QGraphicsItem * pItem = *it; if ((!pItem) || (!farItemReached)) { continue; } if (pItem == farBoundItem) { farItemReached = true; } ThingPaintable * pThingPaintable = ThingPaintable::thingpaintable_cast(pItem); if (!pThingPaintable) { continue; } if (m_excludes.contains(QPointer<ThingPaintable>(pThingPaintable))) { qDebug() << __FUNCTION__ << ": excluding thingpaintable [" << pThingPaintable->objectName() << "]"; continue; } //ok it made it through the gauntlet...append to subjects list m_subjects << QPointer<ThingPaintable>(pThingPaintable); } //if the subjects list contains anything, then set up a pixmapobject... if (m_subjects.isEmpty()) { //nada...bail m_viewport = QRectF(); return; } setupBackingFb(pScene->sceneRect().size().toSize()); m_triggerAble = true; }
void drawKdenliveTitle( producer_ktitle self, mlt_frame frame, int width, int height, double position, int force_refresh ) { // Obtain the producer mlt_producer producer = &self->parent; mlt_profile profile = mlt_service_profile ( MLT_PRODUCER_SERVICE( producer ) ) ; mlt_properties producer_props = MLT_PRODUCER_PROPERTIES( producer ); // Obtain properties of frame mlt_properties properties = MLT_FRAME_PROPERTIES( frame ); pthread_mutex_lock( &self->mutex ); // Check if user wants us to reload the image if ( mlt_properties_get( producer_props, "_animated" ) != NULL || force_refresh == 1 || width != self->current_width || height != self->current_height || mlt_properties_get( producer_props, "_endrect" ) != NULL ) { //mlt_cache_item_close( self->image_cache ); self->current_image = NULL; mlt_properties_set_data( producer_props, "cached_image", NULL, 0, NULL, NULL ); mlt_properties_set_int( producer_props, "force_reload", 0 ); } if (self->current_image == NULL) { // restore QGraphicsScene QGraphicsScene *scene = static_cast<QGraphicsScene *> (mlt_properties_get_data( producer_props, "qscene", NULL )); if ( force_refresh == 1 && scene ) { scene = NULL; mlt_properties_set_data( producer_props, "qscene", NULL, 0, NULL, NULL ); } if ( scene == NULL ) { int argc = 1; char* argv[1]; argv[0] = (char*) "xxx"; // Warning: all Qt graphic objects (QRect, ...) must be initialized AFTER // the QApplication is created, otherwise their will be NULL if ( app == NULL ) { if ( qApp ) { app = qApp; } else { #ifdef linux if ( getenv("DISPLAY") == 0 ) { mlt_log_panic( MLT_PRODUCER_SERVICE( producer ), "Error, cannot render titles without an X11 environment.\nPlease either run melt from an X session or use a fake X server like xvfb:\nxvfb-run -a melt (...)\n" ); pthread_mutex_unlock( &self->mutex ); return; } #endif app = new QApplication( argc, argv ); const char *localename = mlt_properties_get_lcnumeric( MLT_SERVICE_PROPERTIES( MLT_PRODUCER_SERVICE( producer ) ) ); QLocale::setDefault( QLocale( localename ) ); } qRegisterMetaType<QTextCursor>( "QTextCursor" ); } scene = new QGraphicsScene(); scene->setItemIndexMethod( QGraphicsScene::NoIndex ); scene->setSceneRect(0, 0, mlt_properties_get_int( properties, "width" ), mlt_properties_get_int( properties, "height" )); if ( mlt_properties_get( producer_props, "resource" ) && mlt_properties_get( producer_props, "resource" )[0] != '\0' ) { // The title has a resource property, so we read all properties from the resource. // Do not serialize the xmldata loadFromXml( producer, scene, mlt_properties_get( producer_props, "_xmldata" ), mlt_properties_get( producer_props, "templatetext" ) ); } else { // The title has no resource, all data should be serialized loadFromXml( producer, scene, mlt_properties_get( producer_props, "xmldata" ), mlt_properties_get( producer_props, "templatetext" ) ); } mlt_properties_set_data( producer_props, "qscene", scene, 0, ( mlt_destructor )qscene_delete, NULL ); } QRectF start = stringToRect( QString( mlt_properties_get( producer_props, "_startrect" ) ) ); QRectF end = stringToRect( QString( mlt_properties_get( producer_props, "_endrect" ) ) ); int originalWidth = mlt_properties_get_int( producer_props, "_original_width" ); int originalHeight= mlt_properties_get_int( producer_props, "_original_height" ); const QRectF source( 0, 0, width, height ); if (start.isNull()) { start = QRectF( 0, 0, originalWidth, originalHeight ); } // Effects QList <QGraphicsItem *> items = scene->items(); QGraphicsTextItem *titem = NULL; for (int i = 0; i < items.count(); i++) { titem = static_cast <QGraphicsTextItem*> ( items.at( i ) ); if (titem && !titem->data( 0 ).isNull()) { QStringList params = titem->data( 0 ).toStringList(); if (params.at( 0 ) == "typewriter" ) { // typewriter effect has 2 param values: // the keystroke delay and a start offset, both in frames QStringList values = params.at( 2 ).split( ";" ); int interval = qMax( 0, ( ( int ) position - values.at( 1 ).toInt()) / values.at( 0 ).toInt() ); QTextCursor cursor = titem->textCursor(); cursor.movePosition(QTextCursor::EndOfBlock); // get the font format QTextCharFormat format = cursor.charFormat(); cursor.select(QTextCursor::Document); QString txt = params.at( 1 ).left( interval ); // If the string to insert is empty, insert a space / linebreak so that we don't loose // formatting infos for the next iterations int lines = params.at( 1 ).count( '\n' ); QString empty = " "; for (int i = 0; i < lines; i++) empty.append( "\n " ); cursor.insertText( txt.isEmpty() ? empty : txt, format ); if ( !titem->data( 1 ).isNull() ) titem->setTextWidth( titem->data( 1 ).toDouble() ); } } } //must be extracted from kdenlive title QImage img( width, height, QImage::Format_ARGB32 ); img.fill( 0 ); QPainter p1; p1.begin( &img ); p1.setRenderHints( QPainter::Antialiasing | QPainter::TextAntialiasing | QPainter::HighQualityAntialiasing ); //| QPainter::SmoothPixmapTransform ); mlt_position anim_out = mlt_properties_get_position( producer_props, "_animation_out" ); if (end.isNull()) { scene->render( &p1, source, start, Qt::IgnoreAspectRatio ); } else if ( position > anim_out ) { scene->render( &p1, source, end, Qt::IgnoreAspectRatio ); } else { double percentage = 0; if ( position && anim_out ) percentage = position / anim_out; QPointF topleft = start.topLeft() + ( end.topLeft() - start.topLeft() ) * percentage; QPointF bottomRight = start.bottomRight() + ( end.bottomRight() - start.bottomRight() ) * percentage; const QRectF r1( topleft, bottomRight ); scene->render( &p1, source, r1, Qt::IgnoreAspectRatio ); if ( profile && !profile->progressive ){ int line=0; double percentage_next_filed = ( position + 0.5 ) / anim_out; QPointF topleft_next_field = start.topLeft() + ( end.topLeft() - start.topLeft() ) * percentage_next_filed; QPointF bottomRight_next_field = start.bottomRight() + ( end.bottomRight() - start.bottomRight() ) * percentage_next_filed; const QRectF r2( topleft_next_field, bottomRight_next_field ); QImage img1( width, height, QImage::Format_ARGB32 ); img1.fill( 0 ); QPainter p2; p2.begin(&img1); p2.setRenderHints( QPainter::Antialiasing | QPainter::TextAntialiasing | QPainter::HighQualityAntialiasing ); scene->render(&p2,source,r2, Qt::IgnoreAspectRatio ); p2.end(); int next_field_line = ( mlt_properties_get_int( producer_props, "top_field_first" ) ? 1 : 0 ); for (line = next_field_line ;line<height;line+=2){ memcpy(img.scanLine(line),img1.scanLine(line),img.bytesPerLine()); } } } p1.end(); int size = width * height * 4; uint8_t *pointer=img.bits(); QRgb* src = ( QRgb* ) pointer; self->current_image = ( uint8_t * )mlt_pool_alloc( size ); uint8_t *dst = self->current_image; for ( int i = 0; i < width * height * 4; i += 4 ) { *dst++=qRed( *src ); *dst++=qGreen( *src ); *dst++=qBlue( *src ); *dst++=qAlpha( *src ); src++; } mlt_properties_set_data( producer_props, "cached_image", self->current_image, size, mlt_pool_release, NULL ); self->current_width = width; self->current_height = height; } pthread_mutex_unlock( &self->mutex ); mlt_properties_set_int( properties, "width", self->current_width ); mlt_properties_set_int( properties, "height", self->current_height ); }