void HelpBrowser::zoomOut() { qreal zoomFactor = mWebView->zoomFactor(); zoomFactor = qMax( zoomFactor - 0.1, 0.1 ); mWebView->setZoomFactor(zoomFactor); }
void Robot25DWindow::setTaskIndex(int index) { index = qMax(0, qMin(m_game.tasks.size()-1, index)); m_robotView->loadEnvironment(m_game.tasks[index].environment); m_game.index = index; }
void PatternView::paintEvent( QPaintEvent * ) { if( m_needsUpdate == false ) { QPainter p( this ); p.drawPixmap( 0, 0, m_paintPixmap ); return; } QPainter _p( this ); const QColor styleColor = _p.pen().brush().color(); m_pat->changeLength( m_pat->length() ); m_needsUpdate = false; if( m_paintPixmap.isNull() == true || m_paintPixmap.size() != size() ) { m_paintPixmap = QPixmap( size() ); } QPainter p( &m_paintPixmap ); QLinearGradient lingrad( 0, 0, 0, height() ); QColor c; if(( m_pat->m_patternType != Pattern::BeatPattern ) && !( m_pat->getTrack()->isMuted() || m_pat->isMuted() )) { c = styleColor; } else { c = QColor( 80, 80, 80 ); } if( isSelected() == true ) { c.setRgb( qMax( c.red() - 128, 0 ), qMax( c.green() - 128, 0 ), 255 ); } if( m_pat->m_patternType != Pattern::BeatPattern ) { lingrad.setColorAt( 1, c.darker( 300 ) ); lingrad.setColorAt( 0, c ); } else { lingrad.setColorAt( 0, c.darker( 300 ) ); lingrad.setColorAt( 1, c ); } p.setBrush( lingrad ); if( gui->pianoRoll()->currentPattern() == m_pat && m_pat->m_patternType != Pattern::BeatPattern ) p.setPen( c.lighter( 130 ) ); else p.setPen( c.darker( 300 ) ); p.drawRect( QRect( 0, 0, width() - 1, height() - 1 ) ); p.setBrush( QBrush() ); if( m_pat->m_patternType != Pattern::BeatPattern ) { if( gui->pianoRoll()->currentPattern() == m_pat ) p.setPen( c.lighter( 160 ) ); else p.setPen( c.lighter( 130 ) ); p.drawRect( QRect( 1, 1, width() - 3, height() - 3 ) ); } const float ppt = fixedTCOs() ? ( parentWidget()->width() - 2 * TCO_BORDER_WIDTH ) / (float) m_pat->length().getTact() : ( width() - 2 * TCO_BORDER_WIDTH ) / (float) m_pat->length().getTact(); const int x_base = TCO_BORDER_WIDTH; p.setPen( c.darker( 300 ) ); for( tact_t t = 1; t < m_pat->length().getTact(); ++t ) { p.drawLine( x_base + static_cast<int>( ppt * t ) - 1, TCO_BORDER_WIDTH, x_base + static_cast<int>( ppt * t ) - 1, 5 ); p.drawLine( x_base + static_cast<int>( ppt * t ) - 1, height() - ( 4 + 2 * TCO_BORDER_WIDTH ), x_base + static_cast<int>( ppt * t ) - 1, height() - 2 * TCO_BORDER_WIDTH ); } // melody pattern paint event if( m_pat->m_patternType == Pattern::MelodyPattern ) { if( m_pat->m_notes.size() > 0 ) { // first determine the central tone so that we can // display the area where most of the m_notes are // also calculate min/max tones so the tonal range can be // properly stretched accross the pattern vertically int central_key = 0; int max_key = 0; int min_key = 9999999; int total_notes = 0; for( NoteVector::Iterator it = m_pat->m_notes.begin(); it != m_pat->m_notes.end(); ++it ) { if( ( *it )->length() > 0 ) { max_key = qMax( max_key, ( *it )->key() ); min_key = qMin( min_key, ( *it )->key() ); central_key += ( *it )->key(); ++total_notes; } } if( total_notes > 0 ) { central_key = central_key / total_notes; const int keyrange = qMax( qMax( max_key - central_key, central_key - min_key ), 1 ); // debug code // qDebug( "keyrange: %d", keyrange ); // determine height of the pattern view, sans borders const int ht = (height() - 1 - TCO_BORDER_WIDTH * 2) -1; // determine maximum height value for drawing bounds checking const int max_ht = height() - 1 - TCO_BORDER_WIDTH; // set colour based on mute status if( m_pat->getTrack()->isMuted() || m_pat->isMuted() ) { p.setPen( QColor( 160, 160, 160 ) ); } else { p.setPen( fgColor() ); } // scan through all the notes and draw them on the pattern for( NoteVector::Iterator it = m_pat->m_notes.begin(); it != m_pat->m_notes.end(); ++it ) { // calculate relative y-position const float y_key = ( float( central_key - ( *it )->key() ) / keyrange + 1.0f ) / 2; // multiply that by pattern height const int y_pos = static_cast<int>( TCO_BORDER_WIDTH + y_key * ht ) + 1; // debug code // if( ( *it )->length() > 0 ) qDebug( "key %d, central_key %d, y_key %f, y_pos %d", ( *it )->key(), central_key, y_key, y_pos ); // check that note isn't out of bounds, and has a length if( ( *it )->length() > 0 && y_pos >= TCO_BORDER_WIDTH && y_pos <= max_ht ) { // calculate start and end x-coords of the line to be drawn const int x1 = x_base + static_cast<int> ( ( *it )->pos() * ( ppt / MidiTime::ticksPerTact() ) ); const int x2 = x_base + static_cast<int> ( ( ( *it )->pos() + ( *it )->length() ) * ( ppt / MidiTime::ticksPerTact() ) ); // check bounds, draw line if( x1 < width() - TCO_BORDER_WIDTH ) p.drawLine( x1, y_pos, qMin( x2, width() - TCO_BORDER_WIDTH ), y_pos ); } } } } } // beat pattern paint event else if( m_pat->m_patternType == Pattern::BeatPattern && ( fixedTCOs() || ppt >= 96 || m_pat->m_steps != MidiTime::stepsPerTact() ) ) { QPixmap stepon; QPixmap stepoverlay; QPixmap stepoff; QPixmap stepoffl; const int steps = qMax( 1, m_pat->m_steps ); const int w = width() - 2 * TCO_BORDER_WIDTH; // scale step graphics to fit the beat pattern length stepon = s_stepBtnOn->scaled( w / steps, s_stepBtnOn->height(), Qt::IgnoreAspectRatio, Qt::SmoothTransformation ); stepoverlay = s_stepBtnOverlay->scaled( w / steps, s_stepBtnOn->height(), Qt::IgnoreAspectRatio, Qt::SmoothTransformation ); stepoff = s_stepBtnOff->scaled( w / steps, s_stepBtnOff->height(), Qt::IgnoreAspectRatio, Qt::SmoothTransformation ); stepoffl = s_stepBtnOffLight->scaled( w / steps, s_stepBtnOffLight->height(), Qt::IgnoreAspectRatio, Qt::SmoothTransformation ); for( int it = 0; it < steps; it++ ) // go through all the steps in the beat pattern { Note * n = m_pat->noteAtStep( it ); // figure out x and y coordinates for step graphic const int x = TCO_BORDER_WIDTH + static_cast<int>( it * w / steps ); const int y = height() - s_stepBtnOff->height() - 1; // get volume and length of note, if noteAtStep returned null // (meaning, note at step doesn't exist for some reason) // then set both at zero, ie. treat as an off step const int vol = ( n != NULL ? n->getVolume() : 0 ); const int len = ( n != NULL ? int( n->length() ) : 0 ); if( len < 0 ) { p.drawPixmap( x, y, stepoff ); for( int i = 0; i < vol / 5 + 1; ++i ) { p.drawPixmap( x, y, stepon ); } for( int i = 0; i < ( 25 + ( vol - 75 ) ) / 5; ++i ) { p.drawPixmap( x, y, stepoverlay ); } } else if( ( it / 4 ) % 2 ) { p.drawPixmap( x, y, stepoffl ); } else { p.drawPixmap( x, y, stepoff ); } } // end for loop } p.setFont( pointSize<8>( p.font() ) ); QColor text_color = ( m_pat->isMuted() || m_pat->getTrack()->isMuted() ) ? QColor( 30, 30, 30 ) : textColor(); if( m_pat->name() != m_pat->instrumentTrack()->name() ) { p.setPen( QColor( 0, 0, 0 ) ); p.drawText( 4, p.fontMetrics().height()+1, m_pat->name() ); p.setPen( text_color ); p.drawText( 3, p.fontMetrics().height(), m_pat->name() ); } if( m_pat->isMuted() ) { p.drawPixmap( 3, p.fontMetrics().height() + 1, embed::getIconPixmap( "muted", 16, 16 ) ); } p.end(); _p.drawPixmap( 0, 0, m_paintPixmap ); }
/*! Set the base of the scale engine While a base of 10 is what 99.9% of all applications need certain scales might need a different base: f.e 2 The default setting is 10 \param base Base of the engine \sa base() */ void QwtScaleEngine::setBase( uint base ) { d_data->base = qMax( base, 2U ); }
void CornerItem::mouseMoveEvent(QGraphicsSceneMouseEvent * event) { if (m_operation == Off) return; event->accept(); // modify the operation using the shortcuts int op = m_operation; if (event->modifiers() & Qt::ShiftModifier) op &= ~FixScale & ~Rotate; if (event->modifiers() & Qt::ControlModifier) //op |= FixRotate; op |= Rotate; if (event->modifiers() & Qt::AltModifier) //op &= ~(Scale | FixScale); op |= FixRotate; op &= m_opMask; if ((op & (Rotate | Scale)) == (Rotate | Scale)) op |= FixScale; if ((op & (Rotate | Scale)) == Off) return; // vector relative to the centre QPointF v = pos() + event->pos(); if (v.isNull()) return; // do scaling m_content->delayedDirty(); if (op & Scale) { if (op & FixScale) { const double r = m_startRatio; const double D = sqrt(v.x()*v.x() + v.y()*v.y()); const double K = sqrt(1 + 1/(r * r)); int W = qMax((int)((2*D)/(K)), 50); int H = qMax((int)((2*D)/(r*K)), 40); m_content->resizeContents(QRect(-W / 2, -H / 2, W, H)); } else { int W = qMax(2 * fabs(v.x()), 50.0); //(m_contentRect.width() * v.x()) / oldPos.x(); int H = qMax(2 * fabs(v.y()), 40.0); //(m_contentRect.height() * v.y()) / oldPos.y(); //if (W != (int)cRect.width() || H != (int)cRect.height()) m_content->resizeContents(QRect(-W / 2, -H / 2, W, H)); } } // do rotation if (op & Rotate) { QPointF refPos = pos(); // set item rotation (set rotation relative to current) qreal refAngle = atan2(refPos.y(), refPos.x()); qreal newAngle = atan2(v.y(), v.x()); double dZr = 57.29577951308232 * (newAngle - refAngle); // 180 * a / M_PI double zr = m_content->rotation() + dZr; // snap to M_PI/4 if (op & FixRotate) { int fracts = (int)((zr - 7.5) / 15.0); zr = (qreal)fracts * 15.0; } // apply rotation m_content->setRotation(zr); } }
/*! Recalculate the slider's geometry and layout based on the current geometry and fonts. \param update_geometry notify the layout system and call update to redraw the scale */ void QwtSlider::layoutSlider( bool update_geometry ) { int bw = 0; if ( d_data->hasTrough ) bw = d_data->borderWidth; const QSize handleSize = qwtHandleSize( d_data->handleSize, d_data->orientation, d_data->hasTrough ); QRect sliderRect = contentsRect(); /* The marker line of the handle needs to be aligned to the scale. But the marker is in the center and we need space enough to display the rest of the handle. But the scale itself usually needs margins for displaying the tick labels, that also might needs space beyond the backbone. Now it depends on what needs more margins. If it is the slider the scale gets shrunk, otherwise the slider. */ int scaleMargin = 0; if ( d_data->scalePosition != QwtSlider::NoScale ) { int d1, d2; scaleDraw()->getBorderDistHint( font(), d1, d2 ); scaleMargin = qMax( d1, d2 ) - bw; } int scaleX, scaleY, scaleLength; if ( d_data->orientation == Qt::Horizontal ) { const int handleMargin = handleSize.width() / 2 - 1; if ( scaleMargin > handleMargin ) { int off = scaleMargin - handleMargin; sliderRect.adjust( off, 0, -off, 0 ); } scaleX = sliderRect.left() + bw + handleSize.width() / 2 - 1; scaleLength = sliderRect.width() - handleSize.width(); } else { int handleMargin = handleSize.height() / 2 - 1; if ( scaleMargin > handleMargin ) { int off = scaleMargin - handleMargin; sliderRect.adjust( 0, off, 0, -off ); } scaleY = sliderRect.top() + bw + handleSize.height() / 2 - 1; scaleLength = sliderRect.height() - handleSize.height(); } scaleLength -= 2 * bw; // now align slider and scale according to the ScalePosition if ( d_data->orientation == Qt::Horizontal ) { const int h = handleSize.height() + 2 * bw; if ( d_data->scalePosition == QwtSlider::TrailingScale ) { sliderRect.setTop( sliderRect.bottom() + 1 - h ); scaleY = sliderRect.top() - d_data->spacing; } else { sliderRect.setHeight( h ); scaleY = sliderRect.bottom() + 1 + d_data->spacing; } } else // Qt::Vertical { const int w = handleSize.width() + 2 * bw; if ( d_data->scalePosition == QwtSlider::LeadingScale ) { sliderRect.setWidth( w ); scaleX = sliderRect.right() + 1 + d_data->spacing; } else { sliderRect.setLeft( sliderRect.right() + 1 - w ); scaleX = sliderRect.left() - d_data->spacing; } } d_data->sliderRect = sliderRect; scaleDraw()->move( scaleX, scaleY ); scaleDraw()->setLength( scaleLength ); if ( update_geometry ) { d_data->sizeHintCache = QSize(); // invalidate updateGeometry(); update(); } }
/*! \brief Calculate minor/medium ticks for major ticks \param majorTicks Major ticks \param maxMinorSteps Maximum number of minor steps \param stepSize Step size \param minorTicks Array to be filled with the calculated minor ticks \param mediumTicks Array to be filled with the calculated medium ticks */ void QwtLogScaleEngine::buildMinorTicks( const QList<double> &majorTicks, int maxMinorSteps, double stepSize, QList<double> &minorTicks, QList<double> &mediumTicks ) const { const double logBase = base(); if ( stepSize < 1.1 ) // major step width is one base { double minStep = divideInterval( stepSize, maxMinorSteps + 1 ); if ( minStep == 0.0 ) return; const int numSteps = qRound( stepSize / minStep ); int mediumTickIndex = -1; if ( ( numSteps > 2 ) && ( numSteps % 2 == 0 ) ) mediumTickIndex = numSteps / 2; for ( int i = 0; i < majorTicks.count() - 1; i++ ) { const double v = majorTicks[i]; const double s = logBase / numSteps; if ( s >= 1.0 ) { for ( int j = 2; j < numSteps; j++ ) { minorTicks += v * j * s; } } else { for ( int j = 1; j < numSteps; j++ ) { const double tick = v + j * v * ( logBase - 1 ) / numSteps; if ( j == mediumTickIndex ) mediumTicks += tick; else minorTicks += tick; } } } } else { double minStep = divideInterval( stepSize, maxMinorSteps ); if ( minStep == 0.0 ) return; if ( minStep < 1.0 ) minStep = 1.0; // # subticks per interval int numTicks = qRound( stepSize / minStep ) - 1; // Do the minor steps fit into the interval? if ( qwtFuzzyCompare( ( numTicks + 1 ) * minStep, stepSize, stepSize ) > 0 ) { numTicks = 0; } if ( numTicks < 1 ) return; int mediumTickIndex = -1; if ( ( numTicks > 2 ) && ( numTicks % 2 ) ) mediumTickIndex = numTicks / 2; // substep factor = base^substeps const qreal minFactor = qMax( qPow( logBase, minStep ), qreal( logBase ) ); for ( int i = 0; i < majorTicks.count(); i++ ) { double tick = majorTicks[i]; for ( int j = 0; j < numTicks; j++ ) { tick *= minFactor; if ( j == mediumTickIndex ) mediumTicks += tick; else minorTicks += tick; } } } }
void QgsPointDisplacementRenderer::drawGroup( const DisplacementGroup& group, QgsRenderContext& context ) { const QgsFeature& feature = group.begin().value().first; bool selected = mSelectedFeatures.contains( feature.id() ); // maybe we should highlight individual features instead of the whole group? //get list of labels and symbols QStringList labelAttributeList; QList<QgsMarkerSymbolV2*> symbolList; QgsMultiPointV2* groupMultiPoint = new QgsMultiPointV2(); for ( DisplacementGroup::const_iterator attIt = group.constBegin(); attIt != group.constEnd(); ++attIt ) { labelAttributeList << ( mDrawLabels ? getLabel( attIt.value().first ) : QString() ); symbolList << dynamic_cast<QgsMarkerSymbolV2*>( attIt.value().second ); groupMultiPoint->addGeometry( attIt.value().first.constGeometry()->geometry()->clone() ); } //calculate centroid of all points, this will be center of group QgsGeometry groupGeom( groupMultiPoint ); QgsGeometry* centroid = groupGeom.centroid(); QPointF pt; _getPoint( pt, context, QgsConstWkbPtr( centroid->asWkb(), centroid->wkbSize() ) ); delete centroid; //calculate max diagonal size from all symbols in group double diagonal = 0; Q_FOREACH ( QgsMarkerSymbolV2* symbol, symbolList ) { if ( symbol ) { diagonal = qMax( diagonal, QgsSymbolLayerV2Utils::convertToPainterUnits( context, M_SQRT2 * symbol->size(), symbol->outputUnit(), symbol->mapUnitScale() ) ); } } QgsSymbolV2RenderContext symbolContext( context, QgsSymbolV2::MM, 1.0, selected ); QList<QPointF> symbolPositions; QList<QPointF> labelPositions; double circleRadius = -1.0; calculateSymbolAndLabelPositions( symbolContext, pt, symbolList.size(), diagonal, symbolPositions, labelPositions, circleRadius ); //draw Circle if ( circleRadius > 0 ) drawCircle( circleRadius, symbolContext, pt, symbolList.size() ); //draw mid point if ( labelAttributeList.size() > 1 ) { if ( mCenterSymbol ) { mCenterSymbol->renderPoint( pt, &feature, context, -1, selected ); } else { context.painter()->drawRect( QRectF( pt.x() - symbolContext.outputLineWidth( 1 ), pt.y() - symbolContext.outputLineWidth( 1 ), symbolContext.outputLineWidth( 2 ), symbolContext.outputLineWidth( 2 ) ) ); } } //draw symbols on the circle drawSymbols( feature, context, symbolList, symbolPositions, selected ); //and also the labels drawLabels( pt, symbolContext, labelPositions, labelAttributeList ); }
bool ChartShape::Private::loadOdfLabel(KoShape *label, KoXmlElement &labelElement, KoShapeLoadingContext &context) { TextLabelData *labelData = qobject_cast<TextLabelData*>(label->userData()); if (!labelData) return false; // Following will always return false cause KoTextShapeData::loadOdf will try to load // a frame while our text:p is not within a frame. So, let's just not call loadOdf then... //label->loadOdf(labelElement, context); // 1. set the text KoXmlElement pElement = KoXml::namedItemNS(labelElement, KoXmlNS::text, "p"); QTextDocument* doc = labelData->document(); doc->setPlainText(pElement.text()); // 2. set the position QPointF pos = label->position(); bool posChanged = false; if (labelElement.hasAttributeNS(KoXmlNS::svg, "x")) { pos.setX(KoUnit::parseValue(labelElement.attributeNS(KoXmlNS::svg, "x", QString()))); posChanged = true; } if (labelElement.hasAttributeNS(KoXmlNS::svg, "y")) { pos.setY(KoUnit::parseValue(labelElement.attributeNS(KoXmlNS::svg, "y", QString()))); posChanged = true; } if (posChanged) { label->setPosition(pos); } // 3. set the styles if (labelElement.hasAttributeNS(KoXmlNS::chart, "style-name")) { KoStyleStack &styleStack = context.odfLoadingContext().styleStack(); styleStack.clear(); context.odfLoadingContext().fillStyleStack(labelElement, KoXmlNS::chart, "style-name", "chart"); styleStack.setTypeProperties("chart"); if (styleStack.hasProperty(KoXmlNS::style, "rotation-angle")) { qreal rotationAngle = 360 - KoUnit::parseValue(styleStack.property(KoXmlNS::style, "rotation-angle")); label->rotate(rotationAngle); } styleStack.setTypeProperties("text"); if (styleStack.hasProperty(KoXmlNS::fo, "font-size")) { const qreal fontSize = KoUnit::parseValue(styleStack.property(KoXmlNS::fo, "font-size")); QFont font = doc->defaultFont(); font.setPointSizeF(fontSize); doc->setDefaultFont(font); } if (styleStack.hasProperty(KoXmlNS::fo, "font-family")) { const QString fontFamily = styleStack.property(KoXmlNS::fo, "font-family"); QFont font = doc->defaultFont(); font.setFamily(fontFamily); doc->setDefaultFont(font); } } // 4. set the size if (labelElement.hasAttributeNS(KoXmlNS::svg, "width") && labelElement.hasAttributeNS(KoXmlNS::svg, "height")) { const qreal width = KoUnit::parseValue(labelElement.attributeNS(KoXmlNS::svg, "width")); const qreal height = KoUnit::parseValue(labelElement.attributeNS(KoXmlNS::svg, "height")); label->setSize(QSizeF(width, height)); } else { QSizeF size = shape->size(); QRect r = QFontMetrics(doc->defaultFont()).boundingRect( labelData->shapeMargins().left, labelData->shapeMargins().top, qMax(CM_TO_POINT(5), qreal(size.width() - pos.x() * 2.0 - labelData->shapeMargins().right)), qMax(CM_TO_POINT(0.6), qreal(size.height() - labelData->shapeMargins().bottom)), Qt::AlignLeft | Qt::AlignTop | Qt::TextWordWrap, doc->toPlainText()); label->setSize(r.size()); } return true; }
QTextHtmlImporter::Table QTextHtmlImporter::scanTable(int tableNodeIdx) { Table table; table.columns = 0; QVector<QTextLength> columnWidths; int tableHeaderRowCount = 0; QVector<int> rowNodes; rowNodes.reserve(at(tableNodeIdx).children.count()); foreach (int row, at(tableNodeIdx).children) switch (at(row).id) { case Html_tr: rowNodes += row; break; case Html_thead: case Html_tbody: case Html_tfoot: foreach (int potentialRow, at(row).children) if (at(potentialRow).id == Html_tr) { rowNodes += potentialRow; if (at(row).id == Html_thead) ++tableHeaderRowCount; } break; default: break; } QVector<RowColSpanInfo> rowColSpans; QVector<RowColSpanInfo> rowColSpanForColumn; int effectiveRow = 0; foreach (int row, rowNodes) { int colsInRow = 0; foreach (int cell, at(row).children) if (at(cell).isTableCell()) { // skip all columns with spans from previous rows while (colsInRow < rowColSpanForColumn.size()) { const RowColSpanInfo &spanInfo = rowColSpanForColumn[colsInRow]; if (spanInfo.row + spanInfo.rowSpan > effectiveRow) { Q_ASSERT(spanInfo.col == colsInRow); colsInRow += spanInfo.colSpan; } else break; } const QTextHtmlParserNode &c = at(cell); const int currentColumn = colsInRow; colsInRow += c.tableCellColSpan; RowColSpanInfo spanInfo; spanInfo.row = effectiveRow; spanInfo.col = currentColumn; spanInfo.colSpan = c.tableCellColSpan; spanInfo.rowSpan = c.tableCellRowSpan; if (spanInfo.colSpan > 1 || spanInfo.rowSpan > 1) rowColSpans.append(spanInfo); columnWidths.resize(qMax(columnWidths.count(), colsInRow)); rowColSpanForColumn.resize(columnWidths.size()); for (int i = currentColumn; i < currentColumn + c.tableCellColSpan; ++i) { if (columnWidths.at(i).type() == QTextLength::VariableLength) { QTextLength w = c.width; if (c.tableCellColSpan > 1 && w.type() != QTextLength::VariableLength) w = QTextLength(w.type(), w.value(100.) / c.tableCellColSpan); columnWidths[i] = w; } rowColSpanForColumn[i] = spanInfo; } } table.columns = qMax(table.columns, colsInRow); ++effectiveRow; }
void QDeclarativePinchArea::updatePinch() { Q_D(QDeclarativePinchArea); if (d->touchPoints.count() == 0) { if (d->inPinch) { d->stealMouse = false; setKeepMouseGrab(false); d->inPinch = false; QPointF pinchCenter = mapFromScene(d->sceneLastCenter); QDeclarativePinchEvent pe(pinchCenter, d->pinchLastScale, d->pinchLastAngle, d->pinchRotation); pe.setStartCenter(d->pinchStartCenter); pe.setPreviousCenter(pinchCenter); pe.setPreviousAngle(d->pinchLastAngle); pe.setPreviousScale(d->pinchLastScale); pe.setStartPoint1(mapFromScene(d->sceneStartPoint1)); pe.setStartPoint2(mapFromScene(d->sceneStartPoint2)); pe.setPoint1(mapFromScene(d->lastPoint1)); pe.setPoint2(mapFromScene(d->lastPoint2)); emit pinchFinished(&pe); d->pinchStartDist = 0; d->pinchActivated = false; if (d->pinch && d->pinch->target()) d->pinch->setActive(false); } return; } QTouchEvent::TouchPoint touchPoint1 = d->touchPoints.at(0); QTouchEvent::TouchPoint touchPoint2 = d->touchPoints.at(d->touchPoints. count() >= 2 ? 1 : 0); if (d->touchPoints.count() == 2 && (touchPoint1.state() & Qt::TouchPointPressed || touchPoint2.state() & Qt::TouchPointPressed)) { d->id1 = touchPoint1.id(); d->sceneStartPoint1 = touchPoint1.scenePos(); d->sceneStartPoint2 = touchPoint2.scenePos(); d->inPinch = false; d->pinchRejected = false; d->pinchActivated = true; } else if (d->pinchActivated && !d->pinchRejected) { const int dragThreshold = QApplication::startDragDistance(); QPointF p1 = touchPoint1.scenePos(); QPointF p2 = touchPoint2.scenePos(); qreal dx = p1.x() - p2.x(); qreal dy = p1.y() - p2.y(); qreal dist = sqrt(dx*dx + dy*dy); QPointF sceneCenter = (p1 + p2)/2; qreal angle = QLineF(p1, p2).angle(); if (d->touchPoints.count() == 1) { // If we only have one point then just move the center if (d->id1 == touchPoint1.id()) sceneCenter = d->sceneLastCenter + touchPoint1.scenePos() - d->lastPoint1; else sceneCenter = d->sceneLastCenter + touchPoint2.scenePos() - d->lastPoint2; angle = d->pinchLastAngle; } d->id1 = touchPoint1.id(); if (angle > 180) angle -= 360; if (!d->inPinch) { if (d->touchPoints.count() >= 2 && (qAbs(p1.x()-d->sceneStartPoint1.x()) > dragThreshold || qAbs(p1.y()-d->sceneStartPoint1.y()) > dragThreshold || qAbs(p2.x()-d->sceneStartPoint2.x()) > dragThreshold || qAbs(p2.y()-d->sceneStartPoint2.y()) > dragThreshold)) { d->sceneStartCenter = sceneCenter; d->sceneLastCenter = sceneCenter; d->pinchStartCenter = mapFromScene(sceneCenter); d->pinchStartDist = dist; d->pinchStartAngle = angle; d->pinchLastScale = 1.0; d->pinchLastAngle = angle; d->pinchRotation = 0.0; d->lastPoint1 = p1; d->lastPoint2 = p2; QDeclarativePinchEvent pe(d->pinchStartCenter, 1.0, angle, 0.0); pe.setStartCenter(d->pinchStartCenter); pe.setPreviousCenter(d->pinchStartCenter); pe.setPreviousAngle(d->pinchLastAngle); pe.setPreviousScale(d->pinchLastScale); pe.setStartPoint1(mapFromScene(d->sceneStartPoint1)); pe.setStartPoint2(mapFromScene(d->sceneStartPoint2)); pe.setPoint1(mapFromScene(d->lastPoint1)); pe.setPoint2(mapFromScene(d->lastPoint2)); pe.setPointCount(d->touchPoints.count()); emit pinchStarted(&pe); if (pe.accepted()) { d->inPinch = true; d->stealMouse = true; QGraphicsScene *s = scene(); if (s && s->mouseGrabberItem() != this) grabMouse(); setKeepMouseGrab(true); if (d->pinch && d->pinch->target()) { d->pinchStartPos = pinch()->target()->pos(); d->pinchStartScale = d->pinch->target()->scale(); d->pinchStartRotation = d->pinch->target()->rotation(); d->pinch->setActive(true); } } else { d->pinchRejected = true; } } } else if (d->pinchStartDist > 0) { qreal scale = dist ? dist / d->pinchStartDist : d->pinchLastScale; qreal da = d->pinchLastAngle - angle; if (da > 180) da -= 360; else if (da < -180) da += 360; d->pinchRotation += da; QPointF pinchCenter = mapFromScene(sceneCenter); QDeclarativePinchEvent pe(pinchCenter, scale, angle, d->pinchRotation); pe.setStartCenter(d->pinchStartCenter); pe.setPreviousCenter(mapFromScene(d->sceneLastCenter)); pe.setPreviousAngle(d->pinchLastAngle); pe.setPreviousScale(d->pinchLastScale); pe.setStartPoint1(mapFromScene(d->sceneStartPoint1)); pe.setStartPoint2(mapFromScene(d->sceneStartPoint2)); pe.setPoint1(touchPoint1.pos()); pe.setPoint2(touchPoint2.pos()); pe.setPointCount(d->touchPoints.count()); d->pinchLastScale = scale; d->sceneLastCenter = sceneCenter; d->pinchLastAngle = angle; d->lastPoint1 = touchPoint1.scenePos(); d->lastPoint2 = touchPoint2.scenePos(); emit pinchUpdated(&pe); if (d->pinch && d->pinch->target()) { qreal s = d->pinchStartScale * scale; s = qMin(qMax(pinch()->minimumScale(),s), pinch()->maximumScale()); pinch()->target()->setScale(s); QPointF pos = sceneCenter - d->sceneStartCenter + d->pinchStartPos; if (pinch()->axis() & QDeclarativePinch::XAxis) { qreal x = pos.x(); if (x < pinch()->xmin()) x = pinch()->xmin(); else if (x > pinch()->xmax()) x = pinch()->xmax(); pinch()->target()->setX(x); } if (pinch()->axis() & QDeclarativePinch::YAxis) { qreal y = pos.y(); if (y < pinch()->ymin()) y = pinch()->ymin(); else if (y > pinch()->ymax()) y = pinch()->ymax(); pinch()->target()->setY(y); } if (d->pinchStartRotation >= pinch()->minimumRotation() && d->pinchStartRotation <= pinch()->maximumRotation()) { qreal r = d->pinchRotation + d->pinchStartRotation; r = qMin(qMax(pinch()->minimumRotation(),r), pinch()->maximumRotation()); pinch()->target()->setRotation(r); } } } } }
void BezierMode::mousePressEvent(QMouseEvent *m) { const FPoint mousePointDoc = m_canvas->globalToCanvas(m->globalPos()); int z; double Rxp = 0; double Ryp = 0; double Rxpd = 0; double Rypd = 0; PageItem *currItem; // m_canvas->PaintSizeRect(QRect()); FPoint npf, npf2; QRect tx; QTransform pm; m_MouseButtonPressed = true; m_view->HaveSelRect = false; m_doc->DragP = false; m_doc->leaveDrag = false; MoveGX = MoveGY = false; // inItemCreation = false; // oldClip = 0; m->accept(); m_view->registerMousePress(m->globalPos()); Mxp = mousePointDoc.x(); //qRound(m->x()/m_canvas->scale() + 0*m_doc->minCanvasCoordinate.x()); Myp = mousePointDoc.y(); //qRound(m->y()/m_canvas->scale() + 0*m_doc->minCanvasCoordinate.y()); QRect mpo(m->x()-m_doc->guidesPrefs().grabRadius, m->y()-m_doc->guidesPrefs().grabRadius, m_doc->guidesPrefs().grabRadius*2, m_doc->guidesPrefs().grabRadius*2); // mpo.moveBy(qRound(m_doc->minCanvasCoordinate.x() * m_canvas->scale()), qRound(m_doc->minCanvasCoordinate.y() * m_canvas->scale())); Rxp = m_doc->ApplyGridF(FPoint(Mxp, Myp)).x(); Rxpd = Mxp - Rxp; Mxp = qRound(Rxp); Ryp = m_doc->ApplyGridF(FPoint(Mxp, Myp)).y(); Rypd = Myp - Ryp; Myp = qRound(Ryp); SeRx = Mxp; SeRy = Myp; if (m->button() == Qt::MidButton) { m_view->MidButt = true; if (m->modifiers() & Qt::ControlModifier) m_view->DrawNew(); return; } if (m->button() == Qt::RightButton) { m_view->stopGesture(); return; } if (FirstPoly) { selectPage(m); undoManager->setUndoEnabled(false); z = m_doc->itemAdd(PageItem::PolyLine, PageItem::Unspecified, Rxp, Ryp, 1+Rxpd, 1+Rypd, m_doc->itemToolPrefs().lineWidth, CommonStrings::None, m_doc->itemToolPrefs().lineColor); currItem = m_doc->Items->at(z); m_doc->m_Selection->clear(); m_doc->m_Selection->addItem(currItem); m_view->setCursor(QCursor(Qt::CrossCursor)); m_canvas->setRenderModeFillBuffer(); inItemCreation = true; } currItem = m_doc->m_Selection->itemAt(0); // pm.translate(-m_doc->minCanvasCoordinate.x()*m_canvas->scale(), -m_doc->minCanvasCoordinate.y()*m_canvas->scale()); pm = currItem->getTransform(); npf = m_doc->ApplyGridF(mousePointDoc).transformPoint(pm, true); currItem->PoLine.addPoint(npf); npf2 = getMinClipF(&currItem->PoLine); if (npf2.x() < 0) { currItem->PoLine.translate(-npf2.x(), 0); m_doc->moveItem(npf2.x(), 0, currItem); } if (npf2.y() < 0) { currItem->PoLine.translate(0, -npf2.y()); m_doc->moveItem(0, npf2.y(), currItem); } m_doc->sizeItem(currItem->PoLine.WidthHeight().x(), currItem->PoLine.WidthHeight().y(), currItem, false, false, false); currItem->setPolyClip(qRound(qMax(currItem->lineWidth() / 2, 1.0))); m_canvas->newRedrawPolygon(); undoManager->setUndoEnabled(false); }
QString ShaderFactory::genSliceShadowShaderString(bool bit16, float shadowintensity, float r, float g, float b, QList<CropObject> crops, bool peel, int peelType, float peelMin, float peelMax, float peelMix) { bool cropPresent = false; bool tearPresent = false; bool viewPresent = false; bool glowPresent = false; for(int i=0; i<crops.count(); i++) if (crops[i].cropType() < CropObject::Tear_Tear) cropPresent = true; else if (crops[i].cropType() < CropObject::View_Tear) tearPresent = true; else if (crops[i].cropType() < CropObject::Glow_Ball) viewPresent = true; else glowPresent = true; for(int i=0; i<crops.count(); i++) if (crops[i].cropType() >= CropObject::View_Tear && crops[i].cropType() <= CropObject::View_Block && crops[i].magnify() > 1.0) tearPresent = true; bool pathCropPresent = PathShaderFactory::cropPresent(); bool pathViewPresent = PathShaderFactory::blendPresent(); QString shader; float maxrgb = qMax(r, qMax(g, b)); if (maxrgb > 1) maxrgb = 1.0/maxrgb; else maxrgb = 1.0; shader = "#extension GL_ARB_texture_rectangle : enable\n"; shader += "varying vec3 pointpos;\n"; shader += "uniform sampler2D lutTex;\n"; shader += "uniform sampler2DRect dataTex;\n"; shader += "uniform sampler1D paintTex;\n"; shader += "uniform vec3 eyepos;\n"; shader += "uniform float tfSet;\n"; shader += "uniform int gridx;\n"; shader += "uniform int tsizex;\n"; shader += "uniform int tsizey;\n"; shader += "\n"; shader += "uniform sampler2DRect pruneTex;\n"; shader += "uniform int prunegridx;\n"; shader += "uniform int prunetsizex;\n"; shader += "uniform int prunetsizey;\n"; shader += "uniform float prunelod;\n"; shader += "uniform int zoffset;\n"; shader += "uniform vec2 dataMin;\n"; shader += "uniform vec2 dataSize;\n"; shader += "uniform int tminz;\n"; shader += "uniform int lod;\n"; shader += "uniform vec3 dirFront;\n"; shader += "uniform vec3 dirUp;\n"; shader += "uniform vec3 dirRight;\n"; shader += "uniform vec3 brickMin;\n"; shader += "uniform vec3 brickMax;\n"; shader += genTextureCoordinate(); if (tearPresent) shader += TearShaderFactory::generateTear(crops); if (cropPresent) shader += CropShaderFactory::generateCropping(crops); if (glowPresent) shader += GlowShaderFactory::generateGlow(crops); if (viewPresent) shader += BlendShaderFactory::generateBlend(crops); if (pathCropPresent) shader += PathShaderFactory::applyPathCrop(); if (pathViewPresent) shader += PathShaderFactory::applyPathBlend(); shader += "void main(void)\n"; shader += "{\n"; shader += " vec3 texCoord = gl_TexCoord[0].xyz;\n"; shader += "if (any(lessThan(texCoord,brickMin)) || any(greaterThan(texCoord, brickMax)))\n"; shader += " discard;\n"; if (crops.count() > 0) { shader += " vec3 otexCoord = texCoord;\n"; shader += " float feather = 1.0;\n"; } else { if (pathCropPresent) shader += " float feather = 1.0;\n"; if (pathViewPresent) shader += " vec3 otexCoord = texCoord;\n"; } if (glowPresent) { shader += " vec3 glowColor = glow(otexCoord);\n"; shader += " float glowMix = max(glowColor.r, max(glowColor.g, glowColor.b));\n"; shader += " if (glowMix > 0.05) discard;"; } if (tearPresent) { shader += "vec4 tcf = dissect(texCoord);\n"; shader += "texCoord = tcf.xyz;\n"; shader += "feather *= tcf.w;\n"; } if (cropPresent) shader += "feather *= crop(texCoord, true);\n"; if (pathCropPresent) shader += "feather *= pathcrop(texCoord, true);\n"; shader += "texCoord.x = 1.0 + float(tsizex-2)*(texCoord.x-dataMin.x)/dataSize.x;\n"; shader += "texCoord.y = 1.0 + float(tsizey-2)*(texCoord.y-dataMin.y)/dataSize.y;\n"; shader += "texCoord.z = 1.0 + (float(texCoord.z)-float(tminz))/float(lod);\n"; shader += genVgx(); shader += getNormal(); if (bit16) { shader += "int h0 = int(65535.0*vg.x);\n"; shader += "int h1 = h0 / 256;\n"; shader += "h0 = int(mod(float(h0),256.0));\n"; shader += "float fh0 = float(h0)/256.0;\n"; shader += "float fh1 = float(h1)/256.0;\n"; shader += QString("vg.xy = vec2(fh0, fh1*%1 + tfSet);\n").arg(1.0/Global::lutSize()); } else { if (Global::use1D()) shader += " vg.y = tfSet;\n"; else { shader += QString(" vg.y = grad*%1;\n").arg(1.0/Global::lutSize()); shader += " vg.y += tfSet;\n"; } } shader += " gl_FragColor = texture2D(lutTex, vg.xy);\n"; shader += genPeelShader(peel, peelType, peelMin, peelMax, peelMix, false); if (Global::emptySpaceSkip()) { shader += " gl_FragColor.rgba = mix(vec4(0.0,0.0,0.0,0.0), gl_FragColor.rgba, prunefeather.x);\n"; if (PruneHandler::blend()) shader += blendVolume(); else shader += tagVolume(); } if (tearPresent || cropPresent || pathCropPresent) shader += " gl_FragColor.rgba = mix(gl_FragColor.rgba, vec4(0.0,0.0,0.0,0.0), feather);\n"; if (viewPresent) shader += "blend(otexCoord, vg, gl_FragColor);\n"; if (pathViewPresent) shader += "pathblend(otexCoord, vg, gl_FragColor);\n"; //------------------------------------ shader += "gl_FragColor = 1.0-pow((vec4(1,1,1,1)-gl_FragColor),"; shader += "vec4(lod,lod,lod,lod));\n"; //------------------------------------ // --- modulate shadow by homogenity shader += QString(" gl_FragColor.rgba *= 1.0-smoothstep(0.0, float(%1), grad);\n").arg(shadowintensity); shader += " if (gl_FragColor.a < 0.01)\n"; shader += " discard;\n"; shader += "\n"; shader += QString(" gl_FragColor.rgba *= vec4(%1, %2, %3, %4);\n").\ arg(r).arg(g).arg(b).arg(maxrgb); // shader += " gl_FragColor.r = clamp(gl_FragColor.r, 0.0, 1.0);\n"; // shader += " gl_FragColor.g = clamp(gl_FragColor.g, 0.0, 1.0);\n"; // shader += " gl_FragColor.b = clamp(gl_FragColor.b, 0.0, 1.0);\n"; // shader += " gl_FragColor.a = clamp(gl_FragColor.a, 0.0, 1.0);\n"; shader += "}\n"; return shader; }
void UVWidget::paintGL() { glPushAttrib( GL_ALL_ATTRIB_BITS ); glMatrixMode( GL_PROJECTION ); glPushMatrix(); glLoadIdentity(); setupViewport( width(), height() ); glMatrixMode( GL_MODELVIEW ); glPushMatrix(); glLoadIdentity(); qglClearColor( Options::bgColor() ); glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT ); glDisable( GL_DEPTH_TEST ); glDepthMask( GL_FALSE ); // draw texture glPushMatrix(); glLoadIdentity(); glEnable( GL_TEXTURE_2D ); if ( aTextureBlend->isChecked() ) glEnable( GL_BLEND ); else glDisable( GL_BLEND ); if( !texfile.isEmpty() ) bindTexture( texfile ); else bindTexture( texsource ); glTranslatef( -0.5f, -0.5f, 0.0f ); glTranslatef( -1.0f, -1.0f, 0.0f ); for( int i = 0; i < 3; i++ ) { for( int j = 0; j < 3; j++ ) { if( i == 1 && j == 1 ) { glColor4f( 0.75f, 0.75f, 0.75f, 1.0f ); } else { glColor4f( 0.5f, 0.5f, 0.5f, 1.0f ); } glDrawArrays( GL_QUADS, 0, 4 ); glTranslatef( 1.0f, 0.0f, 0.0f ); } glTranslatef( -3.0f, 1.0f, 0.0f ); } glTranslatef( 1.0f, -2.0f, 0.0f ); glDisable( GL_TEXTURE_2D ); glPopMatrix(); // draw grid glPushMatrix(); glLoadIdentity(); glEnable( GL_BLEND ); glLineWidth( 0.8f ); glBegin( GL_LINES ); int glGridMinX = qRound( qMin( glViewRect[0], glViewRect[1] ) / glGridD ); int glGridMaxX = qRound( qMax( glViewRect[0], glViewRect[1] ) / glGridD ); int glGridMinY = qRound( qMin( glViewRect[2], glViewRect[3] ) / glGridD ); int glGridMaxY = qRound( qMax( glViewRect[2], glViewRect[3] ) / glGridD ); for( int i = glGridMinX; i < glGridMaxX; i++ ) { GLdouble glGridPos = glGridD * i; if( ( i % ( GRIDSEGS * GRIDSEGS ) ) == 0 ) { glLineWidth( 1.4f ); glColor4f( 1.0f, 1.0f, 1.0f, 0.4f ); } else if( zoom > ( GRIDSEGS * GRIDSEGS / 2.0 ) ) { continue; } else if( ( i % GRIDSEGS ) == 0 ) { glLineWidth( 1.2f ); glColor4f( 1.0f, 1.0f, 1.0f, 0.2f ); } else if( zoom > ( GRIDSEGS / 2.0 ) ) { continue; } else { glLineWidth( 0.8f ); glColor4f( 1.0f, 1.0f, 1.0f, 0.1f ); } glVertex2d( glGridPos, glViewRect[2] ); glVertex2d( glGridPos, glViewRect[3] ); } for( int i = glGridMinY; i < glGridMaxY; i++ ) { GLdouble glGridPos = glGridD * i; if( ( i % ( GRIDSEGS * GRIDSEGS ) ) == 0 ) { glLineWidth( 1.4f ); glColor4f( 1.0f, 1.0f, 1.0f, 0.4f ); } else if( zoom > ( GRIDSEGS * GRIDSEGS / 2.0 ) ) { continue; } else if( ( i % GRIDSEGS ) == 0 ) { glLineWidth( 1.2f ); glColor4f( 1.0f, 1.0f, 1.0f, 0.2f ); } else if( zoom > ( GRIDSEGS / 2.0 ) ) { continue; } else { glLineWidth( 0.8f ); glColor4f( 1.0f, 1.0f, 1.0f, 0.1f ); } glVertex2d( glViewRect[0], glGridPos ); glVertex2d( glViewRect[1], glGridPos ); } glEnd(); glPopMatrix(); drawTexCoords(); glDisable( GL_DEPTH_TEST ); glDepthMask( GL_FALSE ); if( ! selectRect.isNull() ) { glLoadIdentity(); glHighlightColor(); glBegin( GL_LINE_LOOP ); glVertex( mapToContents( selectRect.topLeft() ) ); glVertex( mapToContents( selectRect.topRight() ) ); glVertex( mapToContents( selectRect.bottomRight() ) ); glVertex( mapToContents( selectRect.bottomLeft() ) ); glEnd(); } if ( ! selectPoly.isEmpty() ) { glLoadIdentity(); glHighlightColor(); glBegin( GL_LINE_LOOP ); foreach ( QPoint p, selectPoly ) { glVertex( mapToContents( p ) ); }
void GlyphStringRenderer::layout() { int width = 0; int height = 0; int lineHeight = 0; int x = 0; int y = 0; prepareGeometryChange(); clear(); if (mGlyphString->state() < GlyphString::LaidOut) return; for (int i = 0; i < mGlyphString->lineInfos().size(); ++i) { width = qMax(width, mGlyphString->lineInfos()[i].width); lineHeight = qMax(lineHeight, mGlyphString->lineInfos()[i].height); height += mGlyphString->lineInfos()[i].height; } width += 10 * mPenWidth; QString paragraphText = mGlyphString->paragraphType() == FRIBIDI_PAR_RTL ? QString("Paragraph base direction: RTL"): QString("Paragraph base direction: LTR"); QFontMetrics fontMetrics(mFont); width = qMax(width, fontMetrics.width(paragraphText + QString("****"))); Arrow paragraphArrow; if (mGlyphString->paragraphType() == FRIBIDI_PAR_RTL) paragraphArrow.init(mFont, paragraphText, mPenWidth, mPenWidth / 2, width - mPenWidth / 2, y, true); else paragraphArrow.init(mFont, paragraphText, mPenWidth, mPenWidth / 2, width - mPenWidth / 2, y, false); if (mFlags & ParagraphArrow) { mArrows.push_back(paragraphArrow); y += paragraphArrow.height(); } for (int i = 0; i < mGlyphString->lineInfos().size(); ++i) { const LineInfo &lineInfo = mGlyphString->lineInfos()[i]; int levelArrowY = y; if (mFlags & LevelArrows) y += paragraphArrow.height(); int runArrowY = y; if (mFlags & RunArrows) y += paragraphArrow.height(); y += lineInfo.ascent; x = (width - lineInfo.width) / 2; x -= lineInfo.left; int offset = mGlyphString->reorderedIndex(lineInfo.startOffset); int lastRun = mGlyphString->run(offset); int lastRunX = x; int lastLevel = mGlyphString->level(offset); int lastLevelX = x; bool lastRunRTL = mGlyphString->runInfos()[lastRun] .direction == HB_DIRECTION_RTL; bool lastLevelRTL = lastLevel & 1; for (int j = lineInfo.startOffset; j < lineInfo.endOffset; ++j) { offset = mGlyphString->reorderedIndex(j); const Geometry &geometry = mGlyphString->geometry(offset); QPoint p; p.setX(x + geometry.left + geometry.xOffset); p.setY(y - geometry.top - geometry.yOffset); if ((mFlags & RunArrows) && (lastRun != mGlyphString->run(offset))) { mArrows.push_back(Arrow(mFont, QString("%1").arg(lastRun), mPenWidth, lastRunX, x, runArrowY, lastRunRTL, mRunArrowColor)); lastRun = mGlyphString->run(offset); lastRunX = x; lastRunRTL = mGlyphString->runInfos()[lastRun] .direction == HB_DIRECTION_RTL; } if ((mFlags & LevelArrows) && (lastLevel != mGlyphString->level(offset))) { mArrows.push_back(Arrow(mFont, QString("%1").arg(lastLevel), mPenWidth, lastLevelX, x, levelArrowY, lastLevelRTL, mLevelArrowColor)); lastLevel = mGlyphString->level(offset); lastLevelX = x; lastLevelRTL = lastLevel & 1; } assert(p.x() >= 0); assert(p.x() + mGlyphString->image(offset).width() <= width); mImagePositions.push_back(p); mImageIndices.push_back(offset); x += geometry.xAdvance; } if (mFlags & RunArrows) { mArrows.push_back(Arrow(mFont, QString("%1").arg(lastRun), mPenWidth, lastRunX, x, runArrowY, lastRunRTL, mRunArrowColor)); } if (mFlags & LevelArrows) { mArrows.push_back(Arrow(mFont, QString("%1").arg(lastLevel), mPenWidth, lastLevelX, x, levelArrowY, lastLevelRTL, mLevelArrowColor)); } y -= lineInfo.ascent; y += lineHeight; } mBoundingRect = QRectF(0, 0, width, y); update(); }
double QgsComposerHtml::findNearbyPageBreak( double yPos ) { if ( !mWebPage || !mRenderedPage || !mUseSmartBreaks ) { return yPos; } //convert yPos to pixels int idealPos = yPos * htmlUnitsToMM(); //if ideal break pos is past end of page, there's nothing we need to do if ( idealPos >= mRenderedPage->height() ) { return yPos; } int maxSearchDistance = mMaxBreakDistance * htmlUnitsToMM(); //loop through all lines just before ideal break location, up to max distance //of maxSearchDistance int changes = 0; QRgb currentColor; QRgb pixelColor; QList< QPair<int, int> > candidates; int minRow = qMax( idealPos - maxSearchDistance, 0 ); for ( int candidateRow = idealPos; candidateRow >= minRow; --candidateRow ) { changes = 0; currentColor = qRgba( 0, 0, 0, 0 ); //check all pixels in this line for ( int col = 0; col < mRenderedPage->width(); ++col ) { //count how many times the pixels change color in this row //eventually, we select a row to break at with the minimum number of color changes //since this is likely a line break, or gap between table cells, etc //but very unlikely to be midway through a text line or picture pixelColor = mRenderedPage->pixel( col, candidateRow ); if ( pixelColor != currentColor ) { //color has changed currentColor = pixelColor; changes++; } } candidates.append( qMakePair( candidateRow, changes ) ); } //sort candidate rows by number of changes ascending, row number descending qSort( candidates.begin(), candidates.end(), candidateSort ); //first candidate is now the largest row with smallest number of changes //ok, now take the mid point of the best candidate position //we do this so that the spacing between text lines is likely to be split in half //otherwise the html will be broken immediately above a line of text, which //looks a little messy int maxCandidateRow = candidates[0].first; int minCandidateRow = maxCandidateRow + 1; int minCandidateChanges = candidates[0].second; QList< QPair<int, int> >::iterator it; for ( it = candidates.begin(); it != candidates.end(); ++it ) { if (( *it ).second != minCandidateChanges || ( *it ).first != minCandidateRow - 1 ) { //no longer in a consecutive block of rows of minimum pixel color changes //so return the row mid-way through the block //first converting back to mm return ( minCandidateRow + ( maxCandidateRow - minCandidateRow ) / 2 ) / htmlUnitsToMM(); } minCandidateRow = ( *it ).first; } //above loop didn't work for some reason //return first candidate converted to mm return candidates[0].first / htmlUnitsToMM(); }
/*! \brief Specify the update interval for automatic scrolling The minimal accepted value is 50 ms. \param interval Update interval in milliseconds \sa setUpdateInterval() */ void QwtSlider::setUpdateInterval( int interval ) { d_data->updateInterval = qMax( interval, 50 ); }
void TequalRand::setTotalRandoms(int total) { if (total / m_range < 256) { m_depth = qMax(1, total / m_range); m_total = total; } }
/*! \return Minimum size hint \sa sizeHint() */ QSize QwtSlider::minimumSizeHint() const { if ( !d_data->sizeHintCache.isEmpty() ) return d_data->sizeHintCache; const QSize handleSize = qwtHandleSize( d_data->handleSize, d_data->orientation, d_data->hasTrough ); int bw = 0; if ( d_data->hasTrough ) bw = d_data->borderWidth; int sliderLength = 0; int scaleExtent = 0; if ( d_data->scalePosition != QwtSlider::NoScale ) { int d1, d2; scaleDraw()->getBorderDistHint( font(), d1, d2 ); const int scaleBorderDist = 2 * ( qMax( d1, d2 ) - bw ); int handleBorderDist; if ( d_data->orientation == Qt::Horizontal ) handleBorderDist = handleSize.width(); else handleBorderDist = handleSize.height(); sliderLength = scaleDraw()->minLength( font() ); if ( handleBorderDist > scaleBorderDist ) { // We need additional space for the overlapping handle sliderLength += handleBorderDist - scaleBorderDist; } scaleExtent += d_data->spacing; scaleExtent += qCeil( scaleDraw()->extent( font() ) ); } sliderLength = qMax( sliderLength, 84 ); // from QSlider int w = 0; int h = 0; if ( d_data->orientation == Qt::Horizontal ) { w = sliderLength; h = handleSize.height() + 2 * bw + scaleExtent; } else { w = handleSize.width() + 2 * bw + scaleExtent; h = sliderLength; } // finally add margins int left, right, top, bottom; getContentsMargins( &left, &top, &right, &bottom ); w += left + right; h += top + bottom; d_data->sizeHintCache = QSize( w, h ); return d_data->sizeHintCache; }
void QWidgetPrivate::setGeometry_sys(int x, int y, int w, int h, bool isMove) { Q_Q(QWidget); if (extra) { // any size restrictions? w = qMin(w,extra->maxw); h = qMin(h,extra->maxh); w = qMax(w,extra->minw); h = qMax(h,extra->minh); } if (q->isWindow() && q->windowHandle()) { QPlatformIntegration *integration = QGuiApplicationPrivate::platformIntegration(); if (!integration->hasCapability(QPlatformIntegration::NonFullScreenWindows)) { x = 0; y = 0; w = q->windowHandle()->width(); h = q->windowHandle()->height(); } } QPoint oldp = q->geometry().topLeft(); QSize olds = q->size(); QRect r(x, y, w, h); bool isResize = olds != r.size(); isMove = oldp != r.topLeft(); //### why do we have isMove as a parameter? // We only care about stuff that changes the geometry, or may // cause the window manager to change its state if (r.size() == olds && oldp == r.topLeft()) return; if (!data.in_set_window_state) { q->data->window_state &= ~Qt::WindowMaximized; q->data->window_state &= ~Qt::WindowFullScreen; if (q->isWindow()) topData()->normalGeometry = QRect(0, 0, -1, -1); } QPoint oldPos = q->pos(); data.crect = r; bool needsShow = false; if (!(data.window_state & Qt::WindowFullScreen) && (w == 0 || h == 0)) { q->setAttribute(Qt::WA_OutsideWSRange, true); if (q->isVisible() && q->testAttribute(Qt::WA_Mapped)) hide_sys(); data.crect = QRect(x, y, w, h); } else if (q->isVisible() && q->testAttribute(Qt::WA_OutsideWSRange)) { q->setAttribute(Qt::WA_OutsideWSRange, false); needsShow = true; } if (q->isVisible()) { if (!q->testAttribute(Qt::WA_DontShowOnScreen) && !q->testAttribute(Qt::WA_OutsideWSRange)) { if (q->windowHandle()) { if (q->isWindow()) { q->windowHandle()->setGeometry(q->geometry()); } else { QPoint posInNativeParent = q->mapTo(q->nativeParentWidget(),QPoint()); q->windowHandle()->setGeometry(QRect(posInNativeParent,r.size())); } const QWidgetBackingStore *bs = maybeBackingStore(); if (bs && bs->store) { if (isResize) bs->store->resize(r.size()); } if (needsShow) show_sys(); } if (!q->isWindow()) { if (isMove && !isResize) moveRect(QRect(oldPos, olds), x - oldPos.x(), y - oldPos.y()); else invalidateBuffer_resizeHelper(oldPos, olds); } } if (isMove) { QMoveEvent e(q->pos(), oldPos); QApplication::sendEvent(q, &e); } if (isResize) { QResizeEvent e(r.size(), olds); QApplication::sendEvent(q, &e); if (q->windowHandle()) q->update(); } } else { // not visible if (isMove && q->pos() != oldPos) q->setAttribute(Qt::WA_PendingMoveEvent, true); if (isResize) q->setAttribute(Qt::WA_PendingResizeEvent, true); } }
void QwtScaleEngine::setMargins( double lower, double upper ) { d_data->lowerMargin = qMax( lower, 0.0 ); d_data->upperMargin = qMax( upper, 0.0 ); }
void QxtSpanSliderPrivate::triggerAction(QAbstractSlider::SliderAction action, bool main) { int value = 0; bool no = false; bool up = false; const int min = qxt_p().minimum(); const int max = qxt_p().maximum(); const SpanHandle altControl = (mainControl == LowerHandle ? UpperHandle : LowerHandle); blockTracking = true; switch (action) { case QAbstractSlider::SliderSingleStepAdd: if ((main && mainControl == UpperHandle) || (!main && altControl == UpperHandle)) { value = qBound(min, upper + qxt_p().singleStep(), max); up = true; break; } value = qBound(min, lower + qxt_p().singleStep(), max); break; case QAbstractSlider::SliderSingleStepSub: if ((main && mainControl == UpperHandle) || (!main && altControl == UpperHandle)) { value = qBound(min, upper - qxt_p().singleStep(), max); up = true; break; } value = qBound(min, lower - qxt_p().singleStep(), max); break; case QAbstractSlider::SliderToMinimum: value = min; if ((main && mainControl == UpperHandle) || (!main && altControl == UpperHandle)) up = true; break; case QAbstractSlider::SliderToMaximum: value = max; if ((main && mainControl == UpperHandle) || (!main && altControl == UpperHandle)) up = true; break; case QAbstractSlider::SliderMove: if ((main && mainControl == UpperHandle) || (!main && altControl == UpperHandle)) up = true; case QAbstractSlider::SliderNoAction: no = true; break; default: qWarning("QxtSpanSliderPrivate::triggerAction: Unknown action"); break; } if (!no && !up) { if (movement == QxtSpanSlider::NoCrossing) value = qMin(value, upper); else if (movement == QxtSpanSlider::NoOverlapping) value = qMin(value, upper - 1); if (movement == QxtSpanSlider::FreeMovement && value > upper) { swapControls(); qxt_p().setUpperPosition(value); } else { qxt_p().setLowerPosition(value); } } else if (!no) { if (movement == QxtSpanSlider::NoCrossing) value = qMax(value, lower); else if (movement == QxtSpanSlider::NoOverlapping) value = qMax(value, lower + 1); if (movement == QxtSpanSlider::FreeMovement && value < lower) { swapControls(); qxt_p().setLowerPosition(value); } else { qxt_p().setUpperPosition(value); } } blockTracking = false; qxt_p().setLowerValue(lowerPos); qxt_p().setUpperValue(upperPos); }
/*! Align and divide an interval \param maxNumSteps Max. number of steps \param x1 First limit of the interval (In/Out) \param x2 Second limit of the interval (In/Out) \param stepSize Step size (Out) \sa QwtScaleEngine::setAttribute() */ void QwtLogScaleEngine::autoScale( int maxNumSteps, double &x1, double &x2, double &stepSize ) const { if ( x1 > x2 ) qSwap( x1, x2 ); const double logBase = base(); QwtInterval interval( x1 / qPow( logBase, lowerMargin() ), x2 * qPow( logBase, upperMargin() ) ); if ( interval.maxValue() / interval.minValue() < logBase ) { // scale width is less than one step -> try to build a linear scale QwtLinearScaleEngine linearScaler; linearScaler.setAttributes( attributes() ); linearScaler.setReference( reference() ); linearScaler.setMargins( lowerMargin(), upperMargin() ); linearScaler.autoScale( maxNumSteps, x1, x2, stepSize ); QwtInterval linearInterval = QwtInterval( x1, x2 ).normalized(); linearInterval = linearInterval.limited( LOG_MIN, LOG_MAX ); if ( linearInterval.maxValue() / linearInterval.minValue() < logBase ) { // the aligned scale is still less than one step if ( stepSize < 0.0 ) stepSize = -qwtLog( logBase, qAbs( stepSize ) ); else stepSize = qwtLog( logBase, stepSize ); return; } } double logRef = 1.0; if ( reference() > LOG_MIN / 2 ) logRef = qMin( reference(), LOG_MAX / 2 ); if ( testAttribute( QwtScaleEngine::Symmetric ) ) { const double delta = qMax( interval.maxValue() / logRef, logRef / interval.minValue() ); interval.setInterval( logRef / delta, logRef * delta ); } if ( testAttribute( QwtScaleEngine::IncludeReference ) ) interval = interval.extend( logRef ); interval = interval.limited( LOG_MIN, LOG_MAX ); if ( interval.width() == 0.0 ) interval = buildInterval( interval.minValue() ); stepSize = divideInterval( qwtLogInterval( logBase, interval ).width(), qMax( maxNumSteps, 1 ) ); if ( stepSize < 1.0 ) stepSize = 1.0; if ( !testAttribute( QwtScaleEngine::Floating ) ) interval = align( interval, stepSize ); x1 = interval.minValue(); x2 = interval.maxValue(); if ( testAttribute( QwtScaleEngine::Inverted ) ) { qSwap( x1, x2 ); stepSize = -stepSize; } }
/*! \property QxtSpanSlider::upperValue \brief the upper value of the span */ int QxtSpanSlider::upperValue() const { return qMax(qxt_d().lower, qxt_d().upper); }
qreal KRITAIMAGE_EXPORT maxDimensionPortion(const QRectF &bounds, qreal portion, qreal minValue) { qreal maxDimension = qMax(bounds.width(), bounds.height()); return qMax(portion * maxDimension, minValue); }
/*! \reimp */ void QxtSpanSlider::mouseMoveEvent(QMouseEvent* event) { if (qxt_d().lowerPressed != QStyle::SC_SliderHandle && qxt_d().upperPressed != QStyle::SC_SliderHandle) { event->ignore(); return; } QStyleOptionSlider opt; qxt_d().initStyleOption(&opt); const int m = style()->pixelMetric(QStyle::PM_MaximumDragDistance, &opt, this); int newPosition = qxt_d().pixelPosToRangeValue(qxt_d().pick(event->pos()) - qxt_d().offset); if (m >= 0) { const QRect r = rect().adjusted(-m, -m, m, m); if (!r.contains(event->pos())) { newPosition = qxt_d().position; } } // pick the preferred handle on the first movement if (qxt_d().firstMovement) { if (qxt_d().lower == qxt_d().upper) { if (newPosition < lowerValue()) { qxt_d().swapControls(); qxt_d().firstMovement = false; } } else { qxt_d().firstMovement = false; } } if (qxt_d().lowerPressed == QStyle::SC_SliderHandle) { if (qxt_d().movement == NoCrossing) { newPosition = qMin(newPosition, upperValue()); } else if (qxt_d().movement == NoOverlapping) { if (qxt_d().fixedInterval) { int span = qxt_d().upperPos - qxt_d().lowerPos; newPosition = qMin(newPosition, upperValue() - 1); newPosition = qMin(newPosition, maximum() - span); setUpperPosition(newPosition + span); } else { newPosition = qMin(newPosition, upperValue() - 1); } } if (qxt_d().movement == FreeMovement && newPosition > qxt_d().upper) { qxt_d().swapControls(); setUpperPosition(newPosition); } else { setLowerPosition(newPosition); } } else if (qxt_d().upperPressed == QStyle::SC_SliderHandle) { if (qxt_d().movement == NoCrossing) newPosition = qMax(newPosition, lowerValue()); else if (qxt_d().movement == NoOverlapping) { if (qxt_d().fixedInterval) { int span = qxt_d().upperPos - qxt_d().lowerPos; newPosition = qMax(newPosition, lowerValue() + 1); newPosition = qMax(newPosition, span); setLowerPosition(newPosition - span); } else { newPosition = qMax(newPosition, lowerValue() + 1); } } if (qxt_d().movement == FreeMovement && newPosition < qxt_d().lower) { qxt_d().swapControls(); setLowerPosition(newPosition); } else { setUpperPosition(newPosition); } } event->accept(); }
void QSlider::setTickInterval(int ts) { d_func()->tickInterval = qMax(0, ts); update(); }
QgsRasterBlock * QgsRasterDataProvider::block( int theBandNo, QgsRectangle const & theExtent, int theWidth, int theHeight ) { QgsDebugMsg( QString( "theBandNo = %1 theWidth = %2 theHeight = %3" ).arg( theBandNo ).arg( theWidth ).arg( theHeight ) ); QgsDebugMsg( QString( "theExtent = %1" ).arg( theExtent.toString() ) ); QgsRasterBlock *block = new QgsRasterBlock( dataType( theBandNo ), theWidth, theHeight, noDataValue( theBandNo ) ); if ( block->isEmpty() ) { QgsDebugMsg( "Couldn't create raster block" ); return block; } // Read necessary extent only QgsRectangle tmpExtent = extent().intersect( &theExtent ); if ( tmpExtent.isEmpty() ) { QgsDebugMsg( "Extent outside provider extent" ); block->setIsNoData(); return block; } double xRes = theExtent.width() / theWidth; double yRes = theExtent.height() / theHeight; double tmpXRes, tmpYRes; double providerXRes = 0; double providerYRes = 0; if ( capabilities() & ExactResolution ) { providerXRes = extent().width() / xSize(); providerYRes = extent().height() / ySize(); tmpXRes = qMax( providerXRes, xRes ); tmpYRes = qMax( providerYRes, yRes ); if ( doubleNear( tmpXRes, xRes ) ) tmpXRes = xRes; if ( doubleNear( tmpYRes, yRes ) ) tmpYRes = yRes; } else { tmpXRes = xRes; tmpYRes = yRes; } if ( tmpExtent != theExtent || tmpXRes > xRes || tmpYRes > yRes ) { // Read smaller extent or lower resolution // Calculate row/col limits (before tmpExtent is aligned) int fromRow = qRound(( theExtent.yMaximum() - tmpExtent.yMaximum() ) / yRes ); int toRow = qRound(( theExtent.yMaximum() - tmpExtent.yMinimum() ) / yRes ) - 1; int fromCol = qRound(( tmpExtent.xMinimum() - theExtent.xMinimum() ) / xRes ) ; int toCol = qRound(( tmpExtent.xMaximum() - theExtent.xMinimum() ) / xRes ) - 1; QgsDebugMsg( QString( "fromRow = %1 toRow = %2 fromCol = %3 toCol = %4" ).arg( fromRow ).arg( toRow ).arg( fromCol ).arg( toCol ) ); if ( fromRow < 0 || fromRow >= theHeight || toRow < 0 || toRow >= theHeight || fromCol < 0 || fromCol >= theWidth || toCol < 0 || toCol >= theWidth ) { // Should not happen QgsDebugMsg( "Row or column limits out of range" ); return block; } // If lower source resolution is used, the extent must beS aligned to original // resolution to avoid possible shift due to resampling if ( tmpXRes > xRes ) { int col = floor(( tmpExtent.xMinimum() - extent().xMinimum() ) / providerXRes ); tmpExtent.setXMinimum( extent().xMinimum() + col * providerXRes ); col = ceil(( tmpExtent.xMaximum() - extent().xMinimum() ) / providerXRes ); tmpExtent.setXMaximum( extent().xMinimum() + col * providerXRes ); } if ( tmpYRes > yRes ) { int row = floor(( extent().yMaximum() - tmpExtent.yMaximum() ) / providerYRes ); tmpExtent.setYMaximum( extent().yMaximum() - row * providerYRes ); row = ceil(( extent().yMaximum() - tmpExtent.yMinimum() ) / providerYRes ); tmpExtent.setYMinimum( extent().yMaximum() - row * providerYRes ); } int tmpWidth = qRound( tmpExtent.width() / tmpXRes ); int tmpHeight = qRound( tmpExtent.height() / tmpYRes ); tmpXRes = tmpExtent.width() / tmpWidth; tmpYRes = tmpExtent.height() / tmpHeight; QgsDebugMsg( QString( "Reading smaller block tmpWidth = %1 theHeight = %2" ).arg( tmpWidth ).arg( tmpHeight ) ); QgsDebugMsg( QString( "tmpExtent = %1" ).arg( tmpExtent.toString() ) ); block->setIsNoData(); QgsRasterBlock *tmpBlock = new QgsRasterBlock( dataType( theBandNo ), tmpWidth, tmpHeight, noDataValue( theBandNo ) ); readBlock( theBandNo, tmpExtent, tmpWidth, tmpHeight, tmpBlock->data() ); int pixelSize = dataTypeSize( theBandNo ); double xMin = theExtent.xMinimum(); double yMax = theExtent.yMaximum(); double tmpXMin = tmpExtent.xMinimum(); double tmpYMax = tmpExtent.yMaximum(); for ( int row = fromRow; row <= toRow; row++ ) { double y = yMax - ( row + 0.5 ) * yRes; int tmpRow = floor(( tmpYMax - y ) / tmpYRes ); for ( int col = fromCol; col <= toCol; col++ ) { double x = xMin + ( col + 0.5 ) * xRes; int tmpCol = floor(( x - tmpXMin ) / tmpXRes ); if ( tmpRow < 0 || tmpRow >= tmpHeight || tmpCol < 0 || tmpCol >= tmpWidth ) { QgsDebugMsg( "Source row or column limits out of range" ); block->setIsNoData(); // so that the problem becomes obvious and fixed delete tmpBlock; return block; } size_t tmpIndex = tmpRow * tmpWidth + tmpCol; size_t index = row * theWidth + col; char *tmpBits = tmpBlock->bits( tmpIndex ); char *bits = block->bits( index ); if ( !tmpBits ) { QgsDebugMsg( QString( "Cannot get input block data tmpRow = %1 tmpCol = %2 tmpIndex = %3." ).arg( tmpRow ).arg( tmpCol ).arg( tmpIndex ) ); continue; } if ( !bits ) { QgsDebugMsg( "Cannot set output block data." ); continue; } memcpy( bits, tmpBits, pixelSize ); } } delete tmpBlock; } else { readBlock( theBandNo, theExtent, theWidth, theHeight, block->data() ); } // apply user no data values // TODO: there are other readBlock methods where no data are not applied QList<QgsRasterBlock::Range> myNoDataRangeList = userNoDataValue( theBandNo ); if ( !myNoDataRangeList.isEmpty() ) { double myNoDataValue = noDataValue( theBandNo ); size_t size = theWidth * theHeight; for ( size_t i = 0; i < size; i++ ) { double value = block->value( i ); if ( QgsRasterBlock::valueInRange( value, myNoDataRangeList ) ) { block->setValue( i, myNoDataValue ); } } } return block; }
// Arranges widgets and returns height required. int PackedLayout::arrange(const QRect& rect, bool set) const { int x = rect.x(); int y = rect.y(); int yrow = 0; QList<QRect> posn; int end = mItems.count(); QList<QLayoutItem*> items; for (int i = 0; i < end; ++i) { QLayoutItem* item = mItems[i]; if (item->isEmpty()) continue; QSize size = item->sizeHint(); int right = x + size.width(); if (right > rect.right() && x > rect.x()) { x = rect.x(); y = y + yrow + spacing(); right = x + size.width(); yrow = size.height(); } else yrow = qMax(yrow, size.height()); items.append(item); posn.append(QRect(QPoint(x, y), size)); x = right + spacing(); } if (set) { int count = items.count(); if (mAlignment == Qt::AlignLeft) { // Left aligned: no position adjustment needed // Set the positions of all the layout items for (int i = 0; i < count; ++i) items[i]->setGeometry(posn[i]); } else { // Set the positions of all the layout items for (int i = 0; i < count; ) { // Adjust item positions a row at a time y = posn[i].y(); int last; // after last item in this row for (last = i + 1; last < count && posn[last].y() == y; ++last) ; int n = last - i; // number of items in this row int free = rect.right() - posn[last - 1].right(); switch (mAlignment) { case Qt::AlignJustify: if (n == 1) { items[i]->setGeometry(posn[i]); ++i; } else if (n > 1) { for (int j = 0; i < last; ++j, ++i) items[i]->setGeometry(QRect(QPoint(posn[i].x() + (free * j)/(n - 1), y), posn[i].size())); } break; case Qt::AlignHCenter: free /= 2; // fall through to AlignRight case Qt::AlignRight: for ( ; i < last; ++i) items[i]->setGeometry(QRect(QPoint(posn[i].x() + free, y), posn[i].size())); break; default: break; } } } } return y + yrow - rect.y(); }
void QGL2PEXVertexArray::addPath(const QVectorPath &path, GLfloat curveInverseScale, bool outline) { const QPointF* const points = reinterpret_cast<const QPointF*>(path.points()); const QPainterPath::ElementType* const elements = path.elements(); if (boundingRectDirty) { minX = maxX = points[0].x(); minY = maxY = points[0].y(); boundingRectDirty = false; } if (!outline && !path.isConvex()) addCentroid(path, 0); int lastMoveTo = vertexArray.size(); vertexArray.add(points[0]); // The first element is always a moveTo do { if (!elements) { // qDebug("QVectorPath has no elements"); // If the path has a null elements pointer, the elements implicitly // start with a moveTo (already added) and continue with lineTos: for (int i=1; i<path.elementCount(); ++i) lineToArray(points[i].x(), points[i].y()); break; } // qDebug("QVectorPath has element types"); for (int i=1; i<path.elementCount(); ++i) { switch (elements[i]) { case QPainterPath::MoveToElement: if (!outline) addClosingLine(lastMoveTo); // qDebug("element[%d] is a MoveToElement", i); vertexArrayStops.add(vertexArray.size()); if (!outline) { if (!path.isConvex()) addCentroid(path, i); lastMoveTo = vertexArray.size(); } lineToArray(points[i].x(), points[i].y()); // Add the moveTo as a new vertex break; case QPainterPath::LineToElement: // qDebug("element[%d] is a LineToElement", i); lineToArray(points[i].x(), points[i].y()); break; case QPainterPath::CurveToElement: { QBezier b = QBezier::fromPoints(*(((const QPointF *) points) + i - 1), points[i], points[i+1], points[i+2]); QRectF bounds = b.bounds(); // threshold based on same algorithm as in qtriangulatingstroker.cpp int threshold = qMin<float>(64, qMax(bounds.width(), bounds.height()) * 3.14f / (curveInverseScale * 6)); if (threshold < 3) threshold = 3; qreal one_over_threshold_minus_1 = qreal(1) / (threshold - 1); for (int t=0; t<threshold; ++t) { QPointF pt = b.pointAt(t * one_over_threshold_minus_1); lineToArray(pt.x(), pt.y()); } i += 2; break; } default: break; } } } while (0); if (!outline) addClosingLine(lastMoveTo); vertexArrayStops.add(vertexArray.size()); }