void QgsComposerRuler::paintEvent( QPaintEvent* event ) { Q_UNUSED( event ); if ( !mComposition ) { return; } QPainter p( this ); QTransform t = mTransform.inverted(); p.setFont( *mRulerFont ); //find optimum scale for ruler (size of numbered divisions) int magnitude = 1; int multiple = 1; int mmDisplay; mmDisplay = optimumScale( mScaleMinPixelsWidth, magnitude, multiple ); //find optimum number of small divisions int numSmallDivisions = optimumNumberDivisions( mmDisplay, multiple ); if ( mDirection == Horizontal ) { if ( qgsDoubleNear( width(), 0 ) ) { return; } //start x-coordinate double startX = t.map( QPointF( 0, 0 ) ).x(); double endX = t.map( QPointF( width(), 0 ) ).x(); //start marker position in mm double markerPos = ( floor( startX / mmDisplay ) + 1 ) * mmDisplay; //draw minor ticks marks which occur before first major tick drawSmallDivisions( &p, markerPos, numSmallDivisions, -mmDisplay ); while ( markerPos <= endX ) { double pixelCoord = mTransform.map( QPointF( markerPos, 0 ) ).x(); //draw large division and text p.drawLine( pixelCoord, 0, pixelCoord, mRulerMinSize ); p.drawText( QPointF( pixelCoord + mPixelsBetweenLineAndText, mTextBaseline ), QString::number( markerPos ) ); //draw small divisions drawSmallDivisions( &p, markerPos, numSmallDivisions, mmDisplay, endX ); markerPos += mmDisplay; } } else //vertical { if ( qgsDoubleNear( height(), 0 ) ) { return; } double startY = t.map( QPointF( 0, 0 ) ).y(); //start position in mm (total including space between pages) double endY = t.map( QPointF( 0, height() ) ).y(); //stop position in mm (total including space between pages) int startPage = ( int )( startY / ( mComposition->paperHeight() + mComposition->spaceBetweenPages() ) ); if ( startPage < 0 ) { startPage = 0; } if ( startY < 0 ) { double beforePageCoord = -mmDisplay; double firstPageY = mTransform.map( QPointF( 0, 0 ) ).y(); //draw negative rulers which fall before first page while ( beforePageCoord > startY ) { double pixelCoord = mTransform.map( QPointF( 0, beforePageCoord ) ).y(); p.drawLine( 0, pixelCoord, mRulerMinSize, pixelCoord ); //calc size of label QString label = QString::number( beforePageCoord ); int labelSize = mRulerFontMetrics->width( label ); //draw label only if it fits in before start of next page if ( pixelCoord + labelSize + 8 < firstPageY ) { drawRotatedText( &p, QPointF( mTextBaseline, pixelCoord + mMinSpacingVerticalLabels + labelSize ), label ); } //draw small divisions drawSmallDivisions( &p, beforePageCoord, numSmallDivisions, mmDisplay ); beforePageCoord -= mmDisplay; } //draw minor ticks marks which occur before first major tick drawSmallDivisions( &p, beforePageCoord + mmDisplay, numSmallDivisions, -mmDisplay, startY ); } int endPage = ( int )( endY / ( mComposition->paperHeight() + mComposition->spaceBetweenPages() ) ); if ( endPage > ( mComposition->numPages() - 1 ) ) { endPage = mComposition->numPages() - 1; } double nextPageStartPos = 0; int nextPageStartPixel = 0; for ( int i = startPage; i <= endPage; ++i ) { double pageCoord = 0; //page coordinate in mm //total (composition) coordinate in mm, including space between pages double totalCoord = i * ( mComposition->paperHeight() + mComposition->spaceBetweenPages() ); //position of next page if ( i < endPage ) { //not the last page nextPageStartPos = ( i + 1 ) * ( mComposition->paperHeight() + mComposition->spaceBetweenPages() ); nextPageStartPixel = mTransform.map( QPointF( 0, nextPageStartPos ) ).y(); } else { //is the last page nextPageStartPos = 0; nextPageStartPixel = 0; } while (( totalCoord < nextPageStartPos ) || (( nextPageStartPos == 0 ) && ( totalCoord <= endY ) ) ) { double pixelCoord = mTransform.map( QPointF( 0, totalCoord ) ).y(); p.drawLine( 0, pixelCoord, mRulerMinSize, pixelCoord ); //calc size of label QString label = QString::number( pageCoord ); int labelSize = mRulerFontMetrics->width( label ); //draw label only if it fits in before start of next page if (( pixelCoord + labelSize + 8 < nextPageStartPixel ) || ( nextPageStartPixel == 0 ) ) { drawRotatedText( &p, QPointF( mTextBaseline, pixelCoord + mMinSpacingVerticalLabels + labelSize ), label ); } //draw small divisions drawSmallDivisions( &p, totalCoord, numSmallDivisions, mmDisplay, nextPageStartPos ); pageCoord += mmDisplay; totalCoord += mmDisplay; } } } //draw current marker pos drawMarkerPos( &p ); }
void QgsLayoutRuler::paintEvent( QPaintEvent *event ) { Q_UNUSED( event ); if ( !mView || !mView->currentLayout() ) { return; } QgsLayout *layout = mView->currentLayout(); QPainter p( this ); drawGuideMarkers( &p, layout ); QTransform t = mTransform.inverted(); p.setFont( mRulerFont ); // keep same default color, but lower opacity a tad QBrush brush = p.brush(); QColor color = brush.color(); color.setAlphaF( 0.7 ); brush.setColor( color ); p.setBrush( brush ); QPen pen = p.pen(); color = pen.color(); color.setAlphaF( 0.7 ); pen.setColor( color ); p.setPen( pen ); //find optimum scale for ruler (size of numbered divisions) int magnitude = 1; int multiple = 1; int mmDisplay = optimumScale( mScaleMinPixelsWidth, magnitude, multiple ); //find optimum number of small divisions int numSmallDivisions = optimumNumberDivisions( mmDisplay, multiple ); switch ( mOrientation ) { case Qt::Horizontal: { if ( qgsDoubleNear( width(), 0 ) ) { return; } //start x-coordinate double startX = t.map( QPointF( 0, 0 ) ).x(); double endX = t.map( QPointF( width(), 0 ) ).x(); //start marker position in mm double markerPos = ( std::floor( startX / mmDisplay ) + 1 ) * mmDisplay; //draw minor ticks marks which occur before first major tick drawSmallDivisions( &p, markerPos, numSmallDivisions, -mmDisplay ); while ( markerPos <= endX ) { double pixelCoord = mTransform.map( QPointF( markerPos, 0 ) ).x(); //draw large division and text p.drawLine( pixelCoord, 0, pixelCoord, mRulerMinSize ); p.drawText( QPointF( pixelCoord + mPixelsBetweenLineAndText, mTextBaseline ), QString::number( markerPos ) ); //draw small divisions drawSmallDivisions( &p, markerPos, numSmallDivisions, mmDisplay, endX ); markerPos += mmDisplay; } break; } case Qt::Vertical: { if ( qgsDoubleNear( height(), 0 ) ) { return; } double startY = t.map( QPointF( 0, 0 ) ).y(); //start position in mm (total including space between pages) double endY = t.map( QPointF( 0, height() ) ).y(); //stop position in mm (total including space between pages) // work out start page int startPage = 0; int endPage = 0; double currentY = 0; double currentPageY = 0; for ( int page = 0; page < layout->pageCollection()->pageCount(); ++page ) { if ( currentY < startY ) { startPage = page; currentPageY = currentY; } endPage = page; currentY += layout->pageCollection()->page( startPage )->rect().height() + layout->pageCollection()->spaceBetweenPages(); if ( currentY > endY ) break; } if ( startY < 0 ) { double beforePageCoord = -mmDisplay; double firstPageY = mTransform.map( QPointF( 0, 0 ) ).y(); //draw negative rulers which fall before first page while ( beforePageCoord > startY ) { double pixelCoord = mTransform.map( QPointF( 0, beforePageCoord ) ).y(); p.drawLine( 0, pixelCoord, mRulerMinSize, pixelCoord ); //calc size of label QString label = QString::number( beforePageCoord ); int labelSize = mRulerFontMetrics->width( label ); //draw label only if it fits in before start of next page if ( pixelCoord + labelSize + 8 < firstPageY ) { drawRotatedText( &p, QPointF( mTextBaseline, pixelCoord + mMinSpacingVerticalLabels + labelSize ), label ); } //draw small divisions drawSmallDivisions( &p, beforePageCoord, numSmallDivisions, mmDisplay ); beforePageCoord -= mmDisplay; } //draw minor ticks marks which occur before first major tick drawSmallDivisions( &p, beforePageCoord + mmDisplay, numSmallDivisions, -mmDisplay, startY ); } double nextPageStartPos = 0; int nextPageStartPixel = 0; for ( int i = startPage; i <= endPage; ++i ) { double pageCoord = 0; //page coordinate in mm //total (composition) coordinate in mm, including space between pages double totalCoord = currentPageY; //position of next page if ( i < endPage ) { //not the last page nextPageStartPos = currentPageY + layout->pageCollection()->page( i )->rect().height() + layout->pageCollection()->spaceBetweenPages(); nextPageStartPixel = mTransform.map( QPointF( 0, nextPageStartPos ) ).y(); } else { //is the last page nextPageStartPos = 0; nextPageStartPixel = 0; } while ( ( totalCoord < nextPageStartPos ) || ( ( nextPageStartPos == 0 ) && ( totalCoord <= endY ) ) ) { double pixelCoord = mTransform.map( QPointF( 0, totalCoord ) ).y(); p.drawLine( 0, pixelCoord, mRulerMinSize, pixelCoord ); //calc size of label QString label = QString::number( pageCoord ); int labelSize = mRulerFontMetrics->width( label ); //draw label only if it fits in before start of next page if ( ( pixelCoord + labelSize + 8 < nextPageStartPixel ) || ( nextPageStartPixel == 0 ) ) { drawRotatedText( &p, QPointF( mTextBaseline, pixelCoord + mMinSpacingVerticalLabels + labelSize ), label ); } //draw small divisions drawSmallDivisions( &p, totalCoord, numSmallDivisions, mmDisplay, nextPageStartPos ); pageCoord += mmDisplay; totalCoord += mmDisplay; } if ( i < endPage ) currentPageY += layout->pageCollection()->page( i )->rect().height() + layout->pageCollection()->spaceBetweenPages(); } break; } } //draw current marker pos drawMarkerPos( &p ); }