예제 #1
0
void HelpBrowser::zoomOut()
{
    qreal zoomFactor = mWebView->zoomFactor();
    zoomFactor = qMax( zoomFactor - 0.1, 0.1 );
    mWebView->setZoomFactor(zoomFactor);
}
예제 #2
0
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;
}
예제 #3
0
파일: Pattern.cpp 프로젝트: diizy/lmms
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 );

}
예제 #4
0
/*!
  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 );
}
예제 #5
0
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);
    }
}
예제 #6
0
/*!
  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();
    }
}
예제 #7
0
/*!
   \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 );
}
예제 #9
0
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;
}
예제 #10
0
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);
}
예제 #13
0
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;
}
예제 #14
0
파일: uvedit.cpp 프로젝트: Alphax/nifskope
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();
}
예제 #16
0
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();
}
예제 #17
0
/*!
  \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 );
}
예제 #18
0
void TequalRand::setTotalRandoms(int total) {
	if (total / m_range < 256) {
		m_depth = qMax(1, total / m_range);
		m_total = total;
	}
}
예제 #19
0
/*!
  \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;
}
예제 #20
0
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);
    }

}
예제 #21
0
void QwtScaleEngine::setMargins( double lower, double upper )
{
    d_data->lowerMargin = qMax( lower, 0.0 );
    d_data->upperMargin = qMax( upper, 0.0 );
}
예제 #22
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);
}
예제 #23
0
/*!
    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;
    }
}
예제 #24
0
/*!
    \property QxtSpanSlider::upperValue
    \brief the upper value of the span
 */
int QxtSpanSlider::upperValue() const
{
    return qMax(qxt_d().lower, qxt_d().upper);
}
예제 #25
0
 qreal KRITAIMAGE_EXPORT maxDimensionPortion(const QRectF &bounds, qreal portion, qreal minValue)
 {
     qreal maxDimension = qMax(bounds.width(), bounds.height());
     return qMax(portion * maxDimension, minValue);
 }
예제 #26
0
/*!
    \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();
}
예제 #27
0
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();
}
예제 #30
0
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());
}