コード例 #1
0
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 );
}
コード例 #2
0
ファイル: qgslayoutruler.cpp プロジェクト: cz172638/QGIS
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 );
}