Example #1
0
    QImage *createImage(const QMatrix &matrix) const
    {
        float sx = qMin(matrix.m11(), matrix.m22());
        float sy = matrix.m22() < sx ? sx : matrix.m22();
//        qWarning("ButtonForeground createImage painter debug. 1");
        QRect scaledRect;
        scaledRect = matrix.mapRect(QRect(0, 0, this->textSize.width(), this->textSize.height()));

        QPainter *painter;
        QImage *imagetext = new QImage(int(scaledRect.width()), int(scaledRect.height()), QImage::Format_ARGB32_Premultiplied);
        imagetext->fill(QColor(0, 0, 0, 0).rgba());
        painter = new QPainter(imagetext);
//        painter->scale(sx, sy);
        QStyleOptionGraphicsItem style;
        this->textItem->paint(painter, &style, 0);
//        qWarning("ButtonForeground createImage painter debug. 2");
        delete painter;
//        qWarning("ButtonForeground createImage painter debug. 3");
        scaledRect = matrix.mapRect(QRect(0, 0, this->logicalSize.width(), this->logicalSize.height()));
        QImage *image = new QImage(int(scaledRect.width()), int(scaledRect.height()), QImage::Format_ARGB32_Premultiplied);
        image->fill(QColor(0, 0, 0, 0).rgba());
        painter = new QPainter(image);
        painter->scale(sx, sy);

        if (this->iconShow)
        {
//            qWarning() << "Icon Size " << this->iconSize << " Pos " << this->iconpos;
            painter->drawImage(this->iconpos*sx, this->icon);
        }

        if (this->textShow)
        {
//            qWarning() << "Text Size " << this->textSize << " Pos " << this->textpos;
            painter->drawImage(this->textpos, *imagetext);
        }

//        qWarning("ButtonForeground createImage painter debug. 4");
        delete imagetext;
        delete painter;
//        qWarning("ButtonForeground createImage painter debug. 5");
        return image;
    }
Example #2
0
void PluckerGenerator::generatePixmap( Okular::PixmapRequest * request )
{
    const QSizeF size = mPages[ request->pageNumber() ]->size();

    QPixmap *pixmap = new QPixmap( request->width(), request->height() );
    pixmap->fill( Qt::white );

    QPainter p;
    p.begin( pixmap );

    qreal width = request->width();
    qreal height = request->height();

    p.scale( width / (qreal)size.width(), height / (qreal)size.height() );
    mPages[ request->pageNumber() ]->drawContents( &p );
    p.end();

    request->page()->setPixmap( request->id(), pixmap );


    if ( !mLinkAdded.contains( request->pageNumber() ) ) {
        QLinkedList<Okular::ObjectRect*> objects;
        for ( int i = 0; i < mLinks.count(); ++i ) {
            if ( mLinks[ i ].page == request->pageNumber() ) {
                QTextDocument *document = mPages[ request->pageNumber() ];

                QRectF rect;
                calculateBoundingRect( document, mLinks[ i ].start,
                                       mLinks[ i ].end, rect );

                objects.append( new Okular::ObjectRect( rect.left(), rect.top(), rect.right(), rect.bottom(), false, Okular::ObjectRect::Action, mLinks[ i ].link ) );
            }
        }

        if ( !objects.isEmpty() )
            request->page()->setObjectRects( objects );

        mLinkAdded.insert( request->pageNumber() );
    }

    signalPixmapRequestDone( request );
}
Example #3
0
void StInterp2::draw(ImageView *view, QPainter &p, int pass) {
    Module::draw(view, p, pass);

    QRectF R = p.clipBoundingRect();
    QRect aR = R.toAlignedRect().intersected(view->image().rect());
    double pt = view->pt2px(1);

    if (view->zoom() > 10) {
        p.save();
        p.scale(1.0/nx, 1.0/ny);
        p.setPen(QPen(Qt::red, nx*0.25*pt));
        cpu_image st2 = publishedImage("st2");
        draw_minor_eigenvector_field(p, st2, QRect(aR.x()*nx, aR.y()*ny, aR.width()*nx, aR.height()*ny));
        p.restore();

        p.setPen(QPen(Qt::blue, 0.5*pt));
        cpu_image st = publishedImage("st");
        draw_minor_eigenvector_field(p, st, aR);
    }
}
Example #4
0
void KWCanvasBase::paintBorder(QPainter &painter, KWViewMode::ViewMap &viewMap)
{
    painter.save();

    const QRectF       pageRect = viewMap.page.rect();
    const KoPageLayout pageLayout = viewMap.page.pageStyle().pageLayout();

    qreal zoomX, zoomY;
    viewConverter()->zoom(&zoomX, &zoomY);
    painter.scale(zoomX, zoomY);

    QPointF topLeftCorner = QPointF(pageRect.topLeft() + QPointF(pageLayout.leftMargin,
                                                                 pageLayout.topMargin));
    QPointF bottomRightCorner = QPointF(pageRect.bottomRight() + QPointF(-pageLayout.rightMargin,
                                                                         -pageLayout.bottomMargin));
    QRectF borderRect = QRectF(topLeftCorner, bottomRightCorner);
    pageLayout.border.paint(painter, borderRect);

    painter.restore();
}
Example #5
0
void PrintJob::printPage(int pageNumber, QPainter &painter)
{
    kDebug(36004) << "Printing page" << pageNumber;
    int sheetPageNumber = pageNumber;
    Sheet* sheet = d->getSheetPageNumber(&sheetPageNumber);

    // Print the cells.
    if (sheet)
    {
        // Reset the offset made for shape printing.
        const double scale = POINT_TO_INCH(printer().resolution());
        const QRect cellRange = d->printManager(sheet)->cellRange(sheetPageNumber);
        const QRectF pageRect = sheet->cellCoordinatesToDocument(cellRange);
        painter.translate(pageRect.left() * scale, pageRect.top() * scale);

        // Scale according to the printer's resolution.
        painter.scale(scale, scale);

        d->printManager(sheet)->printPage(sheetPageNumber, painter);
    }
}
Example #6
0
void BrushEngine::paintDab(const QPointF& point, QPainter& painter) {
    painter.save();
    painter.translate(point);
    painter.rotate(angle);
    painter.scale(1, roundness / 100.0);
    QRectF rect(-size / 2.0, -size / 2.0, size, size);
    painter.drawEllipse(rect);
    painter.restore();
    rect.moveTo(point.x() - size / 2.0, point.y() - size / 2.0);
    if (eraser > 50) {
        canvasItem->update(rect.toRect());
    } else {
        canvasBuffer->update(rect.toRect());
    }

    // Detect a min and max corner positions
    bottomright.setX(qMax(bottomright.x(), qRound(point.x())));
    bottomright.setY(qMax(bottomright.y(), qRound(point.y())));
    topleft.setX(qMin(topleft.x(), qRound(point.x())));
    topleft.setY(qMin(topleft.y(), qRound(point.y())));
}
void MultiLayer::exportPainter(QPainter &painter, bool keepAspect, QRect rect,
                               QSize size) {
  if (size == QSize()) size = canvas->size();
  if (rect == QRect()) rect = canvas->rect();
  if (keepAspect) {
    QSize scaled = rect.size();
    scaled.scale(size, Qt::KeepAspectRatio);
    size = scaled;
  }
  painter.scale((double)size.width() / (double)rect.width(),
                (double)size.height() / (double)rect.height());

  painter.fillRect(rect, backgroundBrush());  // FIXME workaround for background

  for (int i = 0; i < (int)graphsList.count(); i++) {
    Graph *gr = (Graph *)graphsList.at(i);
    Plot *myPlot = (Plot *)gr->plotWidget();

    QPoint pos = QPoint(gr->pos().x(), gr->pos().y());
    gr->exportPainter(painter, false, QRect(pos, myPlot->size()));
  }
}
Example #8
0
// experimental
void PrintLayout::printSixDives() const
{
	ProfileGraphicsView *profile = mainWindow()->graphics();
	QPainter painter;
	painter.begin(printer);
	painter.setRenderHint(QPainter::Antialiasing);
	// painter.setRenderHint(QPainter::HighQualityAntialiasing);
	painter.setRenderHint(QPainter::SmoothPixmapTransform);
	painter.scale(scaleX, scaleY);

	profile->clear();
	profile->setPrintMode(true, !printOptions->color_selected);
	QSize originalSize = profile->size();
	profile->resize(scaledPageW, scaledPageH);

	int i;
	struct dive *dive;
	bool firstPage = true;
	for_each_dive(i, dive) {
		if (!dive->selected && printOptions->print_selected)
			continue;
		// don't create a new page if still on first page
		if (!firstPage)
			printer->newPage();
		else
			firstPage = false;
		profile->plot(dive, true);
		QPixmap pm = QPixmap::grabWidget(profile);
		QTransform transform;
		transform.rotate(270);
		pm = QPixmap(pm.transformed(transform));
		painter.drawPixmap(0, 0, pm);
	}
	painter.end();
	profile->setPrintMode(false);
	profile->resize(originalSize);
	profile->clear();
	profile->plot(current_dive, true);
}
	QImage DocumentAdapter::RenderPage (int page, double xScale, double yScale)
	{
		const auto& size = Doc_->pageSize ();

		auto imgSize = size.toSize ();
		imgSize.rwidth () *= xScale;
		imgSize.rheight () *= yScale;
		QImage image (imgSize, QImage::Format_ARGB32);
		image.fill (Qt::white);

		QRectF rect (QPointF (0, 0), size);
		rect.moveTop (rect.height () * page);

		QPainter painter;
		painter.begin (&image);
		painter.scale (xScale, yScale);
		painter.translate (0, rect.height () * (-page));
		Doc_->drawContents (&painter, rect);
		painter.end ();

		return image;
	}
Example #10
0
QIcon SCgAlphabet::createPairIcon(const QSize &size, QString type)
{
    QIcon icon;

    SCgPair *pair = new SCgPair;
    pair->setTypeAlias(type);

    QVector<QPointF> points;
    points.push_back(QPointF(-size.width() / 2.f, 0.f));
    points.push_back(QPointF(size.width() / 2.f, 0.f));

    pair->setPoints(points);

    QPixmap pixmap(size);
    QPainter painter;

    pixmap.fill(Qt::transparent);

    painter.begin(&pixmap);
    painter.setRenderHint(QPainter::Antialiasing, true);
    pair->setColor(QColor(0, 0, 0, 255));//(state == QIcon::On) ? 255 : 128));

    painter.translate(size.width() / 2.f, size.height() / 2.f);
    painter.scale(0.9f, 0.9f);

    paintPair(&painter, pair);

    painter.end();

    for (int mode = QIcon::Normal; mode <= QIcon::Selected; mode++)
        for (int state = QIcon::On; state <= QIcon::Off; state++)
            icon.addPixmap(pixmap, (QIcon::Mode)mode, (QIcon::State)state);

    delete pair;

    return icon;
}
Example #11
0
void MainWindow::on_pushButton_clicked()
{
    int current_tab = this->ui->tabWidget->currentIndex();

    QPrinter printer;
    QTableView *myWidget;

    switch(current_tab)
    {
    case TABLE::StudentsTableTab:
        myWidget = this->ui->StudentsTableView;
        break;

    case TABLE::TeachersTableTab:
        myWidget = this->ui->TeachersTableView;
        break;
    default:
        return;
    }

    QPixmap pix = myWidget->grab();
    QPainter painter;
    printer.setResolution(QPrinter::HighResolution);

    printer.setPageMargins (15,15,15,15,QPrinter::Millimeter);
    painter.begin(&printer);
    double xscale = printer.pageRect().width()/double(myWidget->width() + 50);
    double yscale = printer.pageRect().height()/double(myWidget->height() + 50);
    double scale = qMin(xscale, yscale);
    painter.scale(scale, scale);

    painter.drawPixmap(0, 0, pix);
    painter.end();

    myWidget->render(&painter);

}
Example #12
0
void QgsLayoutItemLegend::draw( QgsLayoutItemRenderContext &context )
{
  QPainter *painter = context.renderContext().painter();
  painter->save();

  // painter is scaled to dots, so scale back to layout units
  painter->scale( context.renderContext().scaleFactor(), context.renderContext().scaleFactor() );

  painter->setPen( QPen( QColor( 0, 0, 0 ) ) );

  if ( !mSizeToContents )
  {
    // set a clip region to crop out parts of legend which don't fit
    QRectF thisPaintRect = QRectF( 0, 0, rect().width(), rect().height() );
    painter->setClipRect( thisPaintRect );
  }

  QgsLegendRenderer legendRenderer( mLegendModel.get(), mSettings );
  legendRenderer.setLegendSize( mSizeToContents ? QSize() : rect().size() );

  legendRenderer.drawLegend( painter );

  painter->restore();
}
Example #13
0
void AccountsView::print( QPrinter &printer, QPrintDialog &printDialog )
{
    //kDebug(planDbg());
    uint top, left, bottom, right;
    printer.margins( &top, &left, &bottom, &right );
    //kDebug(planDbg())<<m.width()<<"x"<<m.height()<<" :"<<top<<","<<left<<","<<bottom<<","<<right<<" :"<<size();
    QPainter p;
    p.begin( &printer );
    p.setViewport( left, top, printer.width() - left - right, printer.height() - top - bottom );
    p.setClipRect( left, top, printer.width() - left - right, printer.height() - top - bottom );
    QRect preg = p.clipRegion().boundingRect();
    //kDebug(planDbg())<<"p="<<preg;
    //p.drawRect(preg.x(), preg.y(), preg.width()-1, preg.height()-1);
    double scale = qMin( ( double ) preg.width() / ( double ) size().width(), ( double ) preg.height() / ( double ) ( size().height() ) );
    //kDebug(planDbg())<<"scale="<<scale;
    if ( scale < 1.0 ) {
        p.scale( scale, scale );
}
    QPixmap labelPixmap = QPixmap::grabWidget( m_label );
    p.drawPixmap( m_label->pos(), labelPixmap );
    p.translate( 0, m_label->size().height() );
    m_dlv->paintContents( &p );
    p.end();
}
QSizeF QgsSymbolV2LegendNode::drawSymbol( const QgsLegendSettings& settings, ItemContext* ctx, double itemHeight ) const
{
    QgsSymbolV2* s = mItem.symbol();
    if ( !s )
    {
        return QSizeF();
    }

    // setup temporary render context
    QgsRenderContext context;
    context.setScaleFactor( settings.dpi() / 25.4 );
    context.setRendererScale( settings.mapScale() );
    context.setMapToPixel( QgsMapToPixel( 1 / ( settings.mmPerMapUnit() * context.scaleFactor() ) ) );
    context.setForceVectorOutput( true );
    context.setPainter( ctx ? ctx->painter : 0 );

    //Consider symbol size for point markers
    double height = settings.symbolSize().height();
    double width = settings.symbolSize().width();
    double size = 0;
    //Center small marker symbols
    double widthOffset = 0;
    double heightOffset = 0;

    if ( QgsMarkerSymbolV2* markerSymbol = dynamic_cast<QgsMarkerSymbolV2*>( s ) )
    {
        // allow marker symbol to occupy bigger area if necessary
        size = markerSymbol->size() * QgsSymbolLayerV2Utils::lineWidthScaleFactor( context, s->outputUnit(), s->mapUnitScale() ) / context.scaleFactor();
        height = size;
        width = size;
        if ( width < settings.symbolSize().width() )
        {
            widthOffset = ( settings.symbolSize().width() - width ) / 2.0;
        }
        if ( height < settings.symbolSize().height() )
        {
            heightOffset = ( settings.symbolSize().height() - height ) / 2.0;
        }
    }

    if ( ctx )
    {
        double currentXPosition = ctx->point.x();
        double currentYCoord = ctx->point.y() + ( itemHeight - settings.symbolSize().height() ) / 2;
        QPainter* p = ctx->painter;

        //setup painter scaling to dots so that raster symbology is drawn to scale
        double dotsPerMM = context.scaleFactor();

        int opacity = 255;
        if ( QgsVectorLayer* vectorLayer = dynamic_cast<QgsVectorLayer*>( layerNode()->layer() ) )
            opacity = 255 - ( 255 * vectorLayer->layerTransparency() / 100 );

        p->save();
        p->setRenderHint( QPainter::Antialiasing );
        p->translate( currentXPosition + widthOffset, currentYCoord + heightOffset );
        p->scale( 1.0 / dotsPerMM, 1.0 / dotsPerMM );
        if ( opacity != 255 && settings.useAdvancedEffects() )
        {
            //semi transparent layer, so need to draw symbol to an image (to flatten it first)
            //create image which is same size as legend rect, in case symbol bleeds outside its alloted space
            QSize tempImageSize( width * dotsPerMM, height * dotsPerMM );
            QImage tempImage = QImage( tempImageSize, QImage::Format_ARGB32 );
            tempImage.fill( Qt::transparent );
            QPainter imagePainter( &tempImage );
            context.setPainter( &imagePainter );
            s->drawPreviewIcon( &imagePainter, tempImageSize, &context );
            context.setPainter( ctx->painter );
            //reduce opacity of image
            imagePainter.setCompositionMode( QPainter::CompositionMode_DestinationIn );
            imagePainter.fillRect( tempImage.rect(), QColor( 0, 0, 0, opacity ) );
            imagePainter.end();
            //draw rendered symbol image
            p->drawImage( 0, 0, tempImage );
        }
        else
        {
            s->drawPreviewIcon( p, QSize( width * dotsPerMM, height * dotsPerMM ), &context );
        }
        p->restore();
    }

    return QSizeF( qMax( width + 2 * widthOffset, ( double ) settings.symbolSize().width() ),
                   qMax( height + 2 * heightOffset, ( double ) settings.symbolSize().height() ) );
}
Example #15
0
  QColor VQMCSimpleChannelRenderer<ShapeDraw>::
  renderChannel(unsigned camera, unsigned ncameras, 
		const VQMCChannelData& data, 
		const VQMCCameraDataLimits& limits,
		bool clip, QPainter& painter, bool draw_fast)
  {
    QColor background_color = painter.background().color();
    QColor return_color = background_color;
    if(data.fNoDraw)return return_color;
    
    if((!data.fNoData)&&(!data.fSuppress))
      {
	double lim = qMax(fabs(limits.fLimitLo.fValue),
			  fabs(limits.fLimitHi.fValue));
	double x = data.fValue/lim;
	
	if(clip)
	  {
	    if(x>1)x=1;
	    else if(x<-1)x=-1;
	  }

	double radius = 0;

	QColor color = background_color;
	bool found_color = getChannelBaseColor(color, camera, data, limits);
	if((draw_fast)&&(color.alphaF()<1.0))
	  blendColors(1.0-color.alphaF(),color,background_color);
	QBrush brush(color,Qt::SolidPattern);
	
	switch(fValueMode)
	  {
	  case VM_RADIUS:
	    radius = fabs(x);
	    if(x<0)brush.setStyle(Qt::NoBrush);
	    else return_color = color;
	    break;
	  case VM_AREA:
	    radius = sqrt(fabs(x));
	    if(x<0)brush.setStyle(Qt::NoBrush);
	    else return_color = color;
	    break;
	  case VM_ALPHA:
	    if(x>=1)
	      {
		return_color = color;
		radius = 1;
	      }
	    else if(x>0)
	      {
		if(draw_fast)blendColors(x,color,background_color);
		else color.setAlphaF(color.alphaF()*x);
		brush.setColor(color);
		return_color = color;
		radius = 1;
	      }
	    else
	      {
		radius = 0;
	      }
	    break;
	  case VM_COLOR:
	    radius = 1;
	    return_color = color;
	    break;
	  }

	if((found_color)&&(radius>0))
	  {
	    QPen saved_pen = painter.pen();
	    QBrush saved_brush = painter.brush();
	    
	    QPen pen(saved_pen);
	    pen.setWidth(0);
	    if((radius<=1.0)||(!fDrawOutline))pen.setColor(color);
	    else pen.setColor(fOutlineColor);
	    painter.setPen(pen);
	    painter.setBrush(brush);

	    painter.scale(radius,radius);
	    ShapeDraw::draw(camera,ncameras,painter,draw_fast);
	    
	    if((fDrawOutline)&&(radius<=1.0))
	      {
		const qreal rescale = 1.0/radius;
		painter.scale(rescale,rescale);
		pen.setColor(fOutlineColor);
		painter.setPen(pen);
		painter.setBrush(QBrush());
		ShapeDraw::draw(camera,ncameras,painter,draw_fast);
	      }

	    painter.setBrush(saved_brush);
	    painter.setPen(saved_pen);
	  }
	else if(fDrawOutline)
	  {
	    QPen saved_pen = painter.pen();
	    QPen pen = painter.pen();
	    pen.setWidth(0);
	    pen.setColor(fOutlineColor);
	    painter.setPen(pen);
	    ShapeDraw::draw(camera,ncameras,painter,draw_fast);
	    painter.setPen(saved_pen);
	  }
      }
    else if(fDrawOutline)
      {
	QPen saved_pen = painter.pen();
	QPen pen = painter.pen();
	pen.setWidth(0);
	pen.setColor(fOutlineColor);
	painter.setPen(pen);
	ShapeDraw::draw(camera,ncameras,painter,draw_fast);
	painter.setPen(saved_pen);
      }

    return return_color;
  }
Example #16
0
void plotPathsToPainter(QPainter& painter, QPainterPath& path,
			const Numpy1DObj& x, const Numpy1DObj& y,
			const Numpy1DObj* scaling,
			const QRectF* clip,
			const QImage* colorimg,
			bool scaleline)
{
  QRectF cliprect( QPointF(-32767,-32767), QPointF(32767,32767) );
  if( clip != 0 )
    {
      qreal x1, y1, x2, y2;
      clip->getCoords(&x1, &y1, &x2, &y2);
      cliprect.setCoords(x1, y1, x2, y2);
    }
  QRectF pathbox = path.boundingRect();
  cliprect.adjust(pathbox.left(), pathbox.top(),
		  pathbox.bottom(), pathbox.right());

  // keep track of duplicate points
  QPointF lastpt(-1e6, -1e6);
  // keep original transformation for restoration after each iteration
  QTransform origtrans(painter.worldTransform());

  // number of iterations
  int size = min(x.dim, y.dim);

  // if few color points, trim down number of paths
  if( colorimg != 0 )
    size = min(size, colorimg->width());
  // too few scaling points
  if( scaling != 0 )
    size = min(size, scaling->dim);

  // draw each path
  for(int i = 0; i < size; ++i)
    {
      const QPointF pt(x(i), y(i));
      if( cliprect.contains(pt) && ! smallDelta(lastpt, pt) )
	{
	  painter.translate(pt);

	  if( colorimg != 0 )
	    {
	      // get color from pixel and create a new brush
	      QBrush b( QColor::fromRgba(colorimg->pixel(i, 0)) );
	      painter.setBrush(b);
	    }

	  if( scaling == 0 )
	    {
	      painter.drawPath(path);
	    }
	  else
	    {
	      // scale point if requested
	      const qreal s = (*scaling)(i);
	      if( scaleline )
		{
		  painter.scale(s, s);
		  painter.drawPath(path);
		}
	      else
		{
		  QPainterPath scaled;
		  scalePath(path, s, scaled);
		  painter.drawPath(scaled);
		}
	    }

	  painter.setWorldTransform(origtrans);
	  lastpt = pt;
	}
    }
}
Example #17
0
void QgsLayoutTable::render( QgsLayoutItemRenderContext &context, const QRectF &, const int frameIndex )
{
  bool emptyTable = mTableContents.length() == 0;
  if ( emptyTable && mEmptyTableMode == QgsLayoutTable::HideTable )
  {
    //empty table set to hide table mode, so don't draw anything
    return;
  }

  if ( !mLayout->renderContext().isPreviewRender() )
  {
    //exporting composition, so force an attribute refresh
    //we do this in case vector layer has changed via an external source (e.g., another database user)
    refreshAttributes();
  }

  //calculate which rows to show in this frame
  QPair< int, int > rowsToShow = rowRange( frameIndex );

  double gridSizeX = mShowGrid && mVerticalGrid ? mGridStrokeWidth : 0;
  double gridSizeY = mShowGrid && mHorizontalGrid ? mGridStrokeWidth : 0;
  double cellHeaderHeight = QgsLayoutUtils::fontAscentMM( mHeaderFont ) + 2 * mCellMargin;
  double cellBodyHeight = QgsLayoutUtils::fontAscentMM( mContentFont ) + 2 * mCellMargin;
  QRectF cell;

  //calculate whether a header is required
  bool drawHeader = ( ( mHeaderMode == QgsLayoutTable::FirstFrame && frameIndex < 1 )
                      || ( mHeaderMode == QgsLayoutTable::AllFrames ) );
  //calculate whether drawing table contents is required
  bool drawContents = !( emptyTable && mEmptyTableMode == QgsLayoutTable::ShowMessage );

  int numberRowsToDraw = rowsToShow.second - rowsToShow.first;
  int numberEmptyRows = 0;
  if ( drawContents && mShowEmptyRows )
  {
    numberRowsToDraw = rowsVisible( frameIndex, rowsToShow.first, true );
    numberEmptyRows = numberRowsToDraw - rowsToShow.second + rowsToShow.first;
  }
  bool mergeCells = false;
  if ( emptyTable && mEmptyTableMode == QgsLayoutTable::ShowMessage )
  {
    //draw a merged row for the empty table message
    numberRowsToDraw++;
    rowsToShow.second++;
    mergeCells = true;
  }

  QPainter *p = context.renderContext().painter();
  p->save();
  // painter is scaled to dots, so scale back to layout units
  p->scale( context.renderContext().scaleFactor(), context.renderContext().scaleFactor() );

  //draw the text
  p->setPen( Qt::SolidLine );

  double currentX = gridSizeX;
  double currentY = gridSizeY;
  if ( drawHeader )
  {
    //draw the headers
    int col = 0;
    for ( const QgsLayoutTableColumn *column : qgis::as_const( mColumns ) )
    {
      //draw background
      p->save();
      p->setPen( Qt::NoPen );
      p->setBrush( backgroundColor( -1, col ) );
      p->drawRect( QRectF( currentX, currentY, mMaxColumnWidthMap[col] + 2 * mCellMargin, cellHeaderHeight ) );
      p->restore();

      currentX += mCellMargin;

      Qt::TextFlag textFlag = static_cast< Qt::TextFlag >( 0 );
      if ( column->width() <= 0 )
      {
        //automatic column width, so we use the Qt::TextDontClip flag when drawing contents, as this works nicer for italicised text
        //which may slightly exceed the calculated width
        //if column size was manually set then we do apply text clipping, to avoid painting text outside of columns width
        textFlag = Qt::TextDontClip;
      }

      cell = QRectF( currentX, currentY, mMaxColumnWidthMap[col], cellHeaderHeight );

      //calculate alignment of header
      Qt::AlignmentFlag headerAlign = Qt::AlignLeft;
      switch ( mHeaderHAlignment )
      {
        case FollowColumn:
          headerAlign = column->hAlignment();
          break;
        case HeaderLeft:
          headerAlign = Qt::AlignLeft;
          break;
        case HeaderCenter:
          headerAlign = Qt::AlignHCenter;
          break;
        case HeaderRight:
          headerAlign = Qt::AlignRight;
          break;
      }

      QgsLayoutUtils::drawText( p, cell, column->heading(), mHeaderFont, mHeaderFontColor, headerAlign, Qt::AlignVCenter, textFlag );

      currentX += mMaxColumnWidthMap[ col ];
      currentX += mCellMargin;
      currentX += gridSizeX;
      col++;
    }

    currentY += cellHeaderHeight;
    currentY += gridSizeY;
  }

  //now draw the body cells
  int rowsDrawn = 0;
  if ( drawContents )
  {
    //draw the attribute values
    for ( int row = rowsToShow.first; row < rowsToShow.second; ++row )
    {
      rowsDrawn++;
      currentX = gridSizeX;
      int col = 0;

      //calculate row height
      double rowHeight = mMaxRowHeightMap[row + 1] + 2 * mCellMargin;


      for ( const QgsLayoutTableColumn *column : qgis::as_const( mColumns ) )
      {
        //draw background
        p->save();
        p->setPen( Qt::NoPen );
        p->setBrush( backgroundColor( row, col ) );
        p->drawRect( QRectF( currentX, currentY, mMaxColumnWidthMap[col] + 2 * mCellMargin, rowHeight ) );
        p->restore();

        // currentY = gridSize;
        currentX += mCellMargin;

        QVariant cellContents = mTableContents.at( row ).at( col );
        QString str = cellContents.toString();

        Qt::TextFlag textFlag = static_cast< Qt::TextFlag >( 0 );
        if ( column->width() <= 0 && mWrapBehavior == TruncateText )
        {
          //automatic column width, so we use the Qt::TextDontClip flag when drawing contents, as this works nicer for italicised text
          //which may slightly exceed the calculated width
          //if column size was manually set then we do apply text clipping, to avoid painting text outside of columns width
          textFlag = Qt::TextDontClip;
        }
        else if ( textRequiresWrapping( str, column->width(), mContentFont ) )
        {
          str = wrappedText( str, column->width(), mContentFont );
        }

        cell = QRectF( currentX, currentY, mMaxColumnWidthMap[col], rowHeight );
        QgsLayoutUtils::drawText( p, cell, str, mContentFont, mContentFontColor, column->hAlignment(), column->vAlignment(), textFlag );

        currentX += mMaxColumnWidthMap[ col ];
        currentX += mCellMargin;
        currentX += gridSizeX;
        col++;
      }
      currentY += rowHeight;
      currentY += gridSizeY;
    }
  }

  if ( numberRowsToDraw > rowsDrawn )
  {
    p->save();
    p->setPen( Qt::NoPen );

    //draw background of empty rows
    for ( int row = rowsDrawn; row < numberRowsToDraw; ++row )
    {
      currentX = gridSizeX;
      int col = 0;

      if ( mergeCells )
      {
        p->setBrush( backgroundColor( row + 10000, 0 ) );
        p->drawRect( QRectF( gridSizeX, currentY, mTableSize.width() - 2 * gridSizeX, cellBodyHeight ) );
      }
      else
      {
        for ( QgsLayoutTableColumn *column : qgis::as_const( mColumns ) )
        {
          Q_UNUSED( column );

          //draw background

          //we use a bit of a hack here - since we don't want these extra blank rows to match the firstrow/lastrow rule, add 10000 to row number
          p->setBrush( backgroundColor( row + 10000, col ) );
          p->drawRect( QRectF( currentX, currentY, mMaxColumnWidthMap[col] + 2 * mCellMargin, cellBodyHeight ) );

          // currentY = gridSize;
          currentX += mMaxColumnWidthMap[ col ] + 2 * mCellMargin;
          currentX += gridSizeX;
          col++;
        }
      }
      currentY += cellBodyHeight + gridSizeY;
    }
    p->restore();
  }

  //and the borders
  if ( mShowGrid )
  {
    QPen gridPen;
    gridPen.setWidthF( mGridStrokeWidth );
    gridPen.setColor( mGridColor );
    gridPen.setJoinStyle( Qt::MiterJoin );
    p->setPen( gridPen );
    if ( mHorizontalGrid )
    {
      drawHorizontalGridLines( p, rowsToShow.first, rowsToShow.second + numberEmptyRows, drawHeader );
    }
    if ( mVerticalGrid )
    {
      drawVerticalGridLines( p, mMaxColumnWidthMap, rowsToShow.first, rowsToShow.second + numberEmptyRows, drawHeader, mergeCells );
    }
  }

  //special case - no records and table is set to ShowMessage mode
  if ( emptyTable && mEmptyTableMode == QgsLayoutTable::ShowMessage )
  {
    double messageX = gridSizeX + mCellMargin;
    double messageY = gridSizeY + ( drawHeader ? cellHeaderHeight + gridSizeY : 0 );
    cell = QRectF( messageX, messageY, mTableSize.width() - messageX, cellBodyHeight );
    QgsLayoutUtils::drawText( p, cell, mEmptyTableMessage, mContentFont, mContentFontColor, Qt::AlignHCenter, Qt::AlignVCenter, static_cast< Qt::TextFlag >( 0 ) );
  }

  p->restore();

}
Example #18
0
void WindowServerLuna::generateWallpaperImages()
{
	qreal hScale, vScale, wallpaperScale, wallpaperScaleRot = 0.0;

	int screenWidth = SystemUiController::instance()->currentUiWidth();
	int screenHeight = SystemUiController::instance()->currentUiHeight();

	QPixmap image = QPixmap(m_wallpaperFileName);
	if (image.isNull())
		return;

	bool desktop(false);
#ifdef TARGET_DESKTOP
	desktop = true;
#endif

	if(((image.width() < screenWidth) || (image.height() < screenHeight)) && ((image.height() < screenWidth) || (image.width() < screenHeight)) && !desktop) {
		// image is not large enough to fill the screen in any orientation, so do not scale it and
		// draw it centered on the screen
		m_normalWallpaperImage = QPixmap(image.width(), image.height());
		m_rotatedWallpaperImage = QPixmap();

		wallpaperScale = 1;
		m_wallpaperFullScreen = false;
		if (m_normalWallpaperImage.isNull())
			return;
	} else {
		// image can fill the screen in some orientations, so scale it to always fill the entire screen
		m_normalWallpaperImage = QPixmap(m_screenWidth, m_screenHeight);
		m_rotatedWallpaperImage = QPixmap(m_screenWidth, m_screenHeight);

		hScale = (qreal)m_screenWidth / image.width();
		vScale = (qreal)m_screenHeight / image.height();

		if(hScale >= vScale)
			wallpaperScale = hScale;
		else
			wallpaperScale = vScale;

		vScale = (qreal)m_screenHeight / image.width();
		hScale = (qreal)m_screenWidth / image.height();

		if(hScale >= vScale)
			wallpaperScaleRot = hScale;
		else
			wallpaperScaleRot = vScale;

		m_wallpaperFullScreen = true;

		if (m_normalWallpaperImage.isNull())
			return;
		if (m_rotatedWallpaperImage.isNull())
			return;
	}

	QRect target;
	QPainter painter;
	painter.begin(&m_normalWallpaperImage);

	target = QRect((-image.rect().width()/2), (-image.rect().height()/2), image.rect().width(), image.rect().height());

	painter.setRenderHint(QPainter::SmoothPixmapTransform, true);
	painter.translate(m_normalWallpaperImage.width()/2, m_normalWallpaperImage.height()/2);
	painter.scale(wallpaperScale,wallpaperScale);

	painter.drawPixmap(target, image);

	painter.end();

	if(m_wallpaperFullScreen) {// also generate the cropped and rotated version
		painter.begin(&m_rotatedWallpaperImage);

		target = QRect((-image.rect().width()/2), (-image.rect().height()/2), image.rect().width(), image.rect().height());

		painter.setRenderHint(QPainter::SmoothPixmapTransform, true);
		painter.translate(m_rotatedWallpaperImage.width()/2, m_rotatedWallpaperImage.height()/2);
		painter.rotate(90);
		painter.scale(wallpaperScaleRot,wallpaperScaleRot);

		painter.drawPixmap(target, image);

		painter.end();
	}

	if(Settings::LunaSettings()->displayUiRotates) {
		updateWallpaperForRotation(m_currentUiOrientation);
	} else {
		m_currWallpaperImg = &m_normalWallpaperImage;
		Q_EMIT signalWallpaperImageChanged(m_currWallpaperImg, m_wallpaperFullScreen, 0);
	}
}
Example #19
0
/*!
    Prints the frame to the given \a printer.

    \sa render()
*/
void QWebFrame::print(QPrinter *printer) const
{
#if HAVE(QTPRINTSUPPORT)
    QPainter painter;
    if (!painter.begin(printer))
        return;

    const qreal zoomFactorX = (qreal)printer->logicalDpiX() / qt_defaultDpi();
    const qreal zoomFactorY = (qreal)printer->logicalDpiY() / qt_defaultDpi();

    QRect qprinterRect = printer->pageRect();

    QRect pageRect(0, 0, int(qprinterRect.width() / zoomFactorX), int(qprinterRect.height() / zoomFactorY));

    QtPrintContext printContext(&painter, pageRect, d);

    int docCopies;
    int pageCopies;
    if (printer->collateCopies()) {
        docCopies = 1;
        pageCopies = printer->numCopies();
    } else {
        docCopies = printer->numCopies();
        pageCopies = 1;
    }

    int fromPage = printer->fromPage();
    int toPage = printer->toPage();
    bool ascending = true;

    if (!fromPage && !toPage) {
        fromPage = 1;
        toPage = printContext.pageCount();
    }
    // paranoia check
    fromPage = qMax(1, fromPage);
    toPage = qMin(static_cast<int>(printContext.pageCount()), toPage);
    if (toPage < fromPage) {
        // if the user entered a page range outside the actual number
        // of printable pages, just return
        return;
    }

    if (printer->pageOrder() == QPrinter::LastPageFirst) {
        int tmp = fromPage;
        fromPage = toPage;
        toPage = tmp;
        ascending = false;
    }

    painter.scale(zoomFactorX, zoomFactorY);

    for (int i = 0; i < docCopies; ++i) {
        int page = fromPage;
        while (true) {
            for (int j = 0; j < pageCopies; ++j) {
                if (printer->printerState() == QPrinter::Aborted
                    || printer->printerState() == QPrinter::Error) {
                    return;
                }
                printContext.spoolPage(page - 1, pageRect.width());
                if (j < pageCopies - 1)
                    printer->newPage();
            }

            if (page == toPage)
                break;

            if (ascending)
                ++page;
            else
                --page;

            printer->newPage();
        }

        if (i < docCopies - 1)
            printer->newPage();
    }
#endif // HAVE(PRINTSUPPORT)
}
QSizeF QgsSymbolLegendNode::drawSymbol( const QgsLegendSettings &settings, ItemContext *ctx, double itemHeight ) const
{
  QgsSymbol *s = mItem.symbol();
  if ( !s )
  {
    return QSizeF();
  }

  // setup temporary render context
  QgsRenderContext context;
  context.setScaleFactor( settings.dpi() / 25.4 );
  context.setRendererScale( settings.mapScale() );
  context.setMapToPixel( QgsMapToPixel( 1 / ( settings.mmPerMapUnit() * context.scaleFactor() ) ) );
  context.setForceVectorOutput( true );
  context.setPainter( ctx ? ctx->painter : nullptr );

  if ( ctx && ctx->context )
  {
    context.setExpressionContext( ctx->context->expressionContext() );
  }
  else
  {
    // setup a minimal expression context
    QgsExpressionContext expContext;
    expContext.appendScopes( QgsExpressionContextUtils::globalProjectLayerScopes( nullptr ) );
    context.setExpressionContext( expContext );
  }

  //Consider symbol size for point markers
  double height = settings.symbolSize().height();
  double width = settings.symbolSize().width();

  //Center small marker symbols
  double widthOffset = 0;
  double heightOffset = 0;

  if ( QgsMarkerSymbol *markerSymbol = dynamic_cast<QgsMarkerSymbol *>( s ) )
  {
    // allow marker symbol to occupy bigger area if necessary
    double size = markerSymbol->size( context ) / context.scaleFactor();
    height = size;
    width = size;
    if ( width < settings.symbolSize().width() )
    {
      widthOffset = ( settings.symbolSize().width() - width ) / 2.0;
    }
    if ( height < settings.symbolSize().height() )
    {
      heightOffset = ( settings.symbolSize().height() - height ) / 2.0;
    }
  }

  if ( ctx && ctx->painter )
  {
    double currentXPosition = ctx->point.x();
    double currentYCoord = ctx->point.y() + ( itemHeight - settings.symbolSize().height() ) / 2;
    QPainter *p = ctx->painter;

    //setup painter scaling to dots so that raster symbology is drawn to scale
    double dotsPerMM = context.scaleFactor();

    int opacity = 255;
    if ( QgsVectorLayer *vectorLayer = qobject_cast<QgsVectorLayer *>( layerNode()->layer() ) )
      opacity = ( 255 * vectorLayer->opacity() );

    p->save();
    p->setRenderHint( QPainter::Antialiasing );
    p->translate( currentXPosition + widthOffset, currentYCoord + heightOffset );
    p->scale( 1.0 / dotsPerMM, 1.0 / dotsPerMM );
    if ( opacity != 255 && settings.useAdvancedEffects() )
    {
      //semi transparent layer, so need to draw symbol to an image (to flatten it first)
      //create image which is same size as legend rect, in case symbol bleeds outside its alloted space
      QSize tempImageSize( width * dotsPerMM, height * dotsPerMM );
      QImage tempImage = QImage( tempImageSize, QImage::Format_ARGB32 );
      tempImage.fill( Qt::transparent );
      QPainter imagePainter( &tempImage );
      context.setPainter( &imagePainter );
      s->drawPreviewIcon( &imagePainter, tempImageSize, &context );
      context.setPainter( ctx->painter );
      //reduce opacity of image
      imagePainter.setCompositionMode( QPainter::CompositionMode_DestinationIn );
      imagePainter.fillRect( tempImage.rect(), QColor( 0, 0, 0, opacity ) );
      imagePainter.end();
      //draw rendered symbol image
      p->drawImage( 0, 0, tempImage );
    }
    else
    {
      s->drawPreviewIcon( p, QSize( width * dotsPerMM, height * dotsPerMM ), &context );
    }

    if ( !mTextOnSymbolLabel.isEmpty() )
    {
      QFontMetricsF fm( mTextOnSymbolTextFormat.scaledFont( context ) );
      qreal yBaselineVCenter = ( height * dotsPerMM + fm.ascent() - fm.descent() ) / 2;
      QgsTextRenderer::drawText( QPointF( width * dotsPerMM / 2, yBaselineVCenter ), 0, QgsTextRenderer::AlignCenter,
                                 QStringList() << mTextOnSymbolLabel, context, mTextOnSymbolTextFormat );
    }

    p->restore();
  }

  return QSizeF( std::max( width + 2 * widthOffset, static_cast< double >( settings.symbolSize().width() ) ),
                 std::max( height + 2 * heightOffset, static_cast< double >( settings.symbolSize().height() ) ) );
}
Example #21
0
void QgsLabel::renderLabel( QgsRenderContext &renderContext,
                            QgsPoint point,
                            QString text, QFont font, QPen pen,
                            int dx, int dy,
                            double xoffset, double yoffset,
                            double ang,
                            int width, int height, int alignment )
{
  QPainter *painter = renderContext.painter();

  // Convert point to projected units
  if ( renderContext.coordinateTransform() )
  {
    try
    {
      point = renderContext.coordinateTransform()->transform( point );
    }
    catch ( QgsCsException &cse )
    {
      Q_UNUSED( cse ); // unused otherwise
      QgsDebugMsg( "Caught transform error. Skipping rendering this label" );
      return;
    }
  }

  // and then to canvas units
  renderContext.mapToPixel().transform( &point );
  double x = point.x();
  double y = point.y();

  double rad = ang * M_PI / 180;

  x = x + xoffset * cos( rad ) - yoffset * sin( rad );
  y = y - xoffset * sin( rad ) - yoffset * cos( rad );

  painter->save();
  painter->setFont( font );
  painter->translate( x, y );
  //correct oversampled font size back by scaling painter down
  painter->scale( 1.0 / renderContext.rasterScaleFactor(), 1.0 / renderContext.rasterScaleFactor() );
  painter->rotate( -ang );

  //
  // Draw a buffer behind the text if one is desired
  //
  if ( mLabelAttributes->bufferSizeIsSet() && mLabelAttributes->bufferEnabled() )
  {
    double myBufferSize = mLabelAttributes->bufferSize() * 0.3527 * renderContext.scaleFactor() * renderContext.rasterScaleFactor();
    QPen bufferPen;
    if ( mLabelAttributes->bufferColorIsSet() )
    {
      bufferPen.setColor( mLabelAttributes->bufferColor() );
    }
    else //default to a white buffer
    {
      bufferPen.setColor( Qt::white );
    }
    painter->setPen( bufferPen );

    double bufferStepSize; //hack to distinguish pixel devices from logical devices
    if (( renderContext.scaleFactor() - 1 ) > 1.5 )
    {
      bufferStepSize = 1;
    }
    else //draw more dense in case of logical devices
    {
      bufferStepSize = 1 / renderContext.rasterScaleFactor();
    }

    for ( double i = dx - myBufferSize; i <= dx + myBufferSize; i += bufferStepSize )
    {
      for ( double j = dy - myBufferSize; j <= dy + myBufferSize; j += bufferStepSize )
      {
        if ( mLabelAttributes->multilineEnabled() )
          painter->drawText( QRectF( i, j - height, width, height ), alignment, text );
        else
          painter->drawText( QPointF( i, j ), text );
      }
    }
  }

  painter->setPen( pen );
  if ( mLabelAttributes->multilineEnabled() )
    painter->drawText( dx, dy - height, width, height, alignment, text );
  else
    painter->drawText( dx, dy, text );
  painter->restore();
}
Example #22
0
void CachedSvgItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
{
#if defined(Q_OS_WIN)
    // Disable this on windows because the default Qt5 doesn't ship with full OpenGL support
    // https://bugreports.qt-project.org/browse/QTBUG-28715
    // since this is only used for the PFD and the QML PFD is accelerated this is probably
    // a non issue
    QGraphicsSvgItem::paint(painter, option, widget);
#else
    if (painter->paintEngine()->type() != QPaintEngine::OpenGL &&
            painter->paintEngine()->type() != QPaintEngine::OpenGL2) {
        //Fallback to direct painting
        QGraphicsSvgItem::paint(painter, option, widget);
        return;
    }

    QRectF br = boundingRect();
    QTransform transform = painter->worldTransform();
    qreal sceneScale = transform.map(QLineF(0,0,1,0)).length();

    bool stencilTestEnabled = glIsEnabled(GL_STENCIL_TEST);
    bool scissorTestEnabled = glIsEnabled(GL_SCISSOR_TEST);

    painter->beginNativePainting();

    if (stencilTestEnabled)
        glEnable(GL_STENCIL_TEST);
    if (scissorTestEnabled)
        glEnable(GL_SCISSOR_TEST);

    bool dirty = false;
    if (!m_texture) {
        glGenTextures(1, &m_texture);
        m_context = const_cast<QGLContext*>(QGLContext::currentContext());

        dirty = true;
    }

    if (!qFuzzyCompare(sceneScale, m_scale)) {
        m_scale = sceneScale;
        dirty = true;
    }

    int textureWidth = (int(br.width()*m_scale) + 3) & ~3;
    int textureHeight = (int(br.height()*m_scale) + 3) & ~3;

    if (dirty) {
        //qDebug() << "re-render image";

        QImage img(textureWidth, textureHeight, QImage::Format_ARGB32);
        {
            img.fill(Qt::transparent);
            QPainter p;
            p.begin(&img);
            p.setRenderHints(painter->renderHints());
            p.translate(br.topLeft());
            p.scale(m_scale, m_scale);
            QGraphicsSvgItem::paint(&p, option, 0);
            p.end();

            img = img.rgbSwapped();
        }

        glEnable(GL_TEXTURE_2D);

        glBindTexture(GL_TEXTURE_2D, m_texture);
        glTexImage2D(
                GL_TEXTURE_2D,
                0,
                GL_RGBA,
                textureWidth,
                textureHeight,
                0,
                GL_RGBA,
                GL_UNSIGNED_BYTE,
                img.bits());

        glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
        glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
        glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
        glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);

        glDisable(GL_TEXTURE_2D);

        dirty = false;
    }

    glEnable(GL_BLEND);
    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
    glEnable(GL_TEXTURE_2D);

    glBindTexture(GL_TEXTURE_2D, m_texture);

    //texture may be slightly large than svn image, ensure only used area is rendered
    qreal tw = br.width()*m_scale/textureWidth;
    qreal th = br.height()*m_scale/textureHeight;

    glBegin(GL_QUADS);
    glTexCoord2d(0,  0 ); glVertex3d(br.left(), br.top(), -1);
    glTexCoord2d(tw, 0 ); glVertex3d(br.right(), br.top(), -1);
    glTexCoord2d(tw, th); glVertex3d(br.right(), br.bottom(), -1);
    glTexCoord2d(0,  th); glVertex3d(br.left(), br.bottom(), -1);
    glEnd();
    glDisable(GL_TEXTURE_2D);

    painter->endNativePainting();
#endif
}
Example #23
0
void QZint::render(QPainter & painter, const QRectF & paintRect, AspectRatioMode mode)
{
	encode();
	bool textdone;
	int comp_offset = 0, xoffset = m_whitespace, j, main_width = 0, addon_text_height = 0;
	int yoffset = 0;
	QString caption = QString::fromUtf8((const char *)m_zintSymbol->text, -1);
	QFont fontSmall(fontstyle);
	fontSmall.setPixelSize(fontPixelSizeSmall);
	QFont fontLarge(fontstyle);
	fontLarge.setPixelSize(fontPixelSizeLarge);

	if (m_lastError.length())
	{
		painter.setFont(fontLarge);
		painter.drawText(paintRect,Qt::AlignCenter,m_lastError);
		return;
	}

	painter.save();
	painter.setClipRect(paintRect,Qt::IntersectClip);
	qreal xtr=paintRect.x();
	qreal ytr=paintRect.y();

	int zrow_height=m_zintSymbol->height;
	int zrows=0;
	for (int i=0;i<m_zintSymbol->rows;i++)
	{
		zrow_height-=m_zintSymbol->row_height[i];
		if (!m_zintSymbol->row_height[i])
			zrows++;
	}
	if (zrows)
	{
		zrow_height/=zrows;
		for (int i=0;i<m_zintSymbol->rows;i++)
			if (!m_zintSymbol->row_height[i])
				m_zintSymbol->row_height[i]=zrow_height;
	}
	else
		m_zintSymbol->height-=zrow_height;


	qreal gwidth=m_zintSymbol->width;
	qreal gheight=m_zintSymbol->height;
	if (m_zintSymbol->symbology == BARCODE_MAXICODE)
	{
		gheight*=(maxi_width);
		gwidth*=(maxi_width+1);
	}

	qreal xsf=1;
	qreal ysf=1;
	qreal textoffset = 0;

	gwidth+=((m_border==BOX)?m_borderWidth*2:0);
	gheight+=((m_border!=NO_BORDER)?m_borderWidth*2:0);
	if(QString((const char*)m_zintSymbol->text).isEmpty() == false) {
		textoffset = 9;
		gheight += textoffset;
	} else {
		textoffset = 0;
	}
    gwidth+=m_zintSymbol->whitespace_width*2;
	switch(mode)
	{
		case IgnoreAspectRatio:
				xsf=(qreal)paintRect.width()/gwidth;
				ysf=(qreal)paintRect.height()/gheight;
			break;

		case KeepAspectRatio:
			if (paintRect.width()/gwidth<paintRect.height()/gheight)
			{
				ysf=xsf=(qreal)paintRect.width()/gwidth;
				ytr+=(qreal)(paintRect.height()-gheight*ysf)/2;
			}
			else
			{
				ysf=xsf=(qreal)paintRect.height()/gheight;
				xtr+=(qreal)(paintRect.width()-gwidth*xsf)/2;
			}
			break;

		case CenterBarCode:
				xtr+=((qreal)paintRect.width()-gwidth*xsf)/2;
				ytr+=((qreal)paintRect.height()-gheight*ysf)/2;
			break;
	}

	painter.setBackground(QBrush(m_bgColor));
	painter.fillRect(paintRect,QBrush(m_bgColor));
	painter.translate(xtr,ytr);
	painter.scale(xsf,ysf);

	QPen p;
	p.setColor(m_fgColor);
	p.setWidth(m_borderWidth);
	painter.setPen(p);

	QPainterPath pt;
	if(m_zintSymbol->symbology != BARCODE_MAXICODE) {
		/* Draw boundary bars or boxes around the symbol */
		switch(m_border)
		{
			case BOX:
				painter.fillRect(0,m_borderWidth,m_borderWidth,m_zintSymbol->height,QBrush(m_fgColor));
				painter.fillRect(m_zintSymbol->width + xoffset + xoffset + m_borderWidth,m_borderWidth,m_borderWidth,m_zintSymbol->height,QBrush(m_fgColor));
				painter.fillRect(0,0,m_zintSymbol->width + xoffset + xoffset + m_borderWidth + m_borderWidth,m_borderWidth,QBrush(m_fgColor));
				painter.fillRect(0,m_zintSymbol->height + m_borderWidth,m_zintSymbol->width + xoffset + xoffset + m_borderWidth + m_borderWidth, m_borderWidth,QBrush(m_fgColor));
				painter.translate(m_borderWidth+m_zintSymbol->whitespace_width,m_borderWidth);
				yoffset = m_borderWidth;
				break;
			case BIND:
				painter.fillRect(0,0,m_zintSymbol->width + xoffset + xoffset,m_borderWidth,QBrush(m_fgColor));
				painter.fillRect(0,m_zintSymbol->height + m_borderWidth,m_zintSymbol->width + xoffset + xoffset, m_borderWidth,QBrush(m_fgColor));
				painter.translate(m_zintSymbol->whitespace_width,m_borderWidth);
				yoffset = m_borderWidth;
				break;
	
			default:
				painter.translate(m_zintSymbol->whitespace_width,0);
				break;;
		}
	}

	while(!(module_set(m_zintSymbol->rows - 1, comp_offset))) {
		comp_offset++;
	}
	xoffset = comp_offset;
	
	/* Set up some values for displaying EAN and UPC symbols correctly */
	main_width = m_zintSymbol->width;
	if ((((m_zintSymbol->symbology == BARCODE_EANX) && (m_zintSymbol->rows == 1)) || (m_zintSymbol->symbology == BARCODE_EANX_CC))
		|| (m_zintSymbol->symbology == BARCODE_ISBNX)) {
		switch(caption.size()) {
			case 13: /* EAN 13 */
			case 16:
			case 19:
				if(m_zintSymbol->whitespace_width == 0) {
					m_zintSymbol->whitespace_width = 10;
				}
				main_width = 96 + comp_offset;
				break;
			default:
				main_width = 68 + comp_offset;
				break;
		}
	}
	
	if (((m_zintSymbol->symbology == BARCODE_UPCA) && (m_zintSymbol->rows == 1)) || (m_zintSymbol->symbology == BARCODE_UPCA_CC)) {
		if(m_zintSymbol->whitespace_width == 0) {
			m_zintSymbol->whitespace_width = 10;
		}
		main_width = 96 + comp_offset;
	}
	
	if (((m_zintSymbol->symbology == BARCODE_UPCE) && (m_zintSymbol->rows == 1)) || (m_zintSymbol->symbology == BARCODE_UPCE_CC)) {
		if(m_zintSymbol->whitespace_width == 0) {
			m_zintSymbol->whitespace_width = 10;
		}
		main_width = 51 + comp_offset;
	}
	
	p.setWidth(1);
	painter.setPen(p);

	if (m_zintSymbol->symbology == BARCODE_MAXICODE)
	{
		/* Draw Maxicode with hexagons */
		painter.save();
		painter.setRenderHint(QPainter::Antialiasing);
		for (int r=0;r<m_zintSymbol->rows;r++)
		{
			for (int c=0;c<m_zintSymbol->width;c++)
			{
				if (module_set(r, c))
				{
					qreal col=(qreal)c*(maxi_width+1)+(r%2)*((maxi_width+1)/2);
					qreal row=(qreal)r*(maxi_width+1)*0.868;
					QPainterPath pt;
					pt.moveTo(col+maxi_width/2, 	row);
					pt.lineTo(col+maxi_width, 	row+maxi_diagonal/4);
					pt.lineTo(col+maxi_width, 	row+(maxi_diagonal-maxi_diagonal/4));
					pt.lineTo(col+maxi_width/2, 	row+maxi_diagonal);
					pt.lineTo(col, 			row+(maxi_diagonal-maxi_diagonal/4));
					pt.lineTo(col, 			row+maxi_diagonal/4);
					pt.lineTo(col+maxi_width/2, 	row);
					painter.fillPath(pt,QBrush(m_fgColor));
				}
			}
		}
		p.setWidth(maxi_width);
		painter.setPen(p);
		const qreal w=maxi_width+1;
		painter.drawEllipse(QPointF(14.5*w,16.5*w*0.868),w,w);
		painter.drawEllipse(QPointF(14.5*w,16.5*w*0.868),w+w*1.5,w+w*1.5);
		painter.drawEllipse(QPointF(14.5*w,16.5*w*0.868),w+w*3,w+w*3);
		painter.restore();
	}
	else
	{
		/* Draw all other symbols with rectangles */
		int y=0;
		for (int row=0;row<m_zintSymbol->rows;row++)
		{
			for (int i=0;i<m_zintSymbol->width;i++) {
				if (module_set(row, i))
				{
					int ed = module_set(row, i);
					int linewidth=0;
					for (int j=i;j<m_zintSymbol->width;j++,linewidth++)
						if (ed != module_set(row, j))
							break;
					QColor color;
					color=m_fgColor;
					
					if(!((i > main_width) && (row == m_zintSymbol->rows - 1)))  {
						painter.fillRect(i,y,linewidth,m_zintSymbol->row_height[row],QBrush(color));
					} else {
						painter.fillRect(i,y + 8,linewidth,m_zintSymbol->row_height[row] - 3,QBrush(color));
						addon_text_height = y;
					}
				}
			}
			/* Add row binding */
			if(((m_zintSymbol->symbology == BARCODE_CODE16K) || (m_zintSymbol->symbology == BARCODE_CODE49)) && (row != 0)) {
				painter.fillRect(0,y - 1,m_zintSymbol->width,2,QBrush(m_fgColor));
			}
			y+=m_zintSymbol->row_height[row];
		}
	}

	textdone = false;
	
	if(m_hidetext == false) {
		painter.setFont(fontSmall);
		if(((m_zintSymbol->symbology == BARCODE_EANX) || (m_zintSymbol->symbology == BARCODE_EANX_CC)) ||
			(m_zintSymbol->symbology == BARCODE_ISBNX)) {
			/* Add bridge and format text for EAN */
			switch(caption.size()) {
				case 8:
				case 11:
				case 14:
					painter.fillRect(0 + xoffset,m_zintSymbol->height,1,5,QBrush(m_fgColor));
					painter.fillRect(2 + xoffset,m_zintSymbol->height,1,5,QBrush(m_fgColor));
					painter.fillRect(32 + xoffset,m_zintSymbol->height,1,5,QBrush(m_fgColor));
					painter.fillRect(34 + xoffset,m_zintSymbol->height,1,5,QBrush(m_fgColor));
					painter.fillRect(64 + xoffset,m_zintSymbol->height,1,5,QBrush(m_fgColor));
					painter.fillRect(66 + xoffset,m_zintSymbol->height,1,5,QBrush(m_fgColor));
					painter.setFont(fontLarge);
					painter.drawText(3 + xoffset, m_zintSymbol->height + yoffset, 29, 9,Qt::AlignCenter, caption.mid(0,4));
					painter.drawText(35 + xoffset, m_zintSymbol->height + yoffset, 29, 9,Qt::AlignCenter, caption.mid(4,4));
					if(caption.size() == 11) { /* EAN-2 */ painter.drawText(76 + xoffset, addon_text_height, 20, 9,Qt::AlignCenter, caption.mid(9,2)); };
					if(caption.size() == 14) { /* EAN-5 */ painter.drawText(76 + xoffset, addon_text_height, 47, 9,Qt::AlignCenter, caption.mid(9,5)); };
					painter.setFont(fontSmall);
					textdone = true;
					break;
				case 13:
				case 16:
				case 19:
					painter.fillRect(0 + xoffset,m_zintSymbol->height,1,5,QBrush(m_fgColor));
					painter.fillRect(2 + xoffset,m_zintSymbol->height,1,5,QBrush(m_fgColor));
					painter.fillRect(46 + xoffset,m_zintSymbol->height,1,5,QBrush(m_fgColor));
					painter.fillRect(48 + xoffset,m_zintSymbol->height,1,5,QBrush(m_fgColor));
					painter.fillRect(92 + xoffset,m_zintSymbol->height,1,5,QBrush(m_fgColor));
					painter.fillRect(94 + xoffset,m_zintSymbol->height,1,5,QBrush(m_fgColor));
					painter.setFont(fontLarge);
					painter.drawText(xoffset - 7, m_zintSymbol->height + yoffset, 7, 9,Qt::AlignCenter, caption.mid(0,1));
					painter.drawText(3 + xoffset, m_zintSymbol->height + yoffset, 43, 9,Qt::AlignCenter, caption.mid(1,6));
					painter.drawText(49 + xoffset, m_zintSymbol->height + yoffset, 43, 9,Qt::AlignCenter, caption.mid(7,6));
					if(caption.size() == 16) { /* EAN-2 */ painter.drawText(104 + xoffset, addon_text_height, 20, 9,Qt::AlignCenter, caption.mid(14,2)); };
					if(caption.size() == 19) { /* EAN-5 */ painter.drawText(104 + xoffset, addon_text_height, 47, 9,Qt::AlignCenter, caption.mid(14,5)); };
					painter.setFont(fontSmall);
					textdone = true;
					break;
			}
			if(textdone == false) {
				painter.setFont(fontLarge);
				painter.drawText(0, m_zintSymbol->height, m_zintSymbol->width, 9,Qt::AlignCenter, caption);
				painter.setFont(fontSmall);
				textdone = true;
			}
		}
		
		if((m_zintSymbol->symbology == BARCODE_UPCA) || (m_zintSymbol->symbology == BARCODE_UPCA_CC)) {
			/* Add bridge and format text for UPC-A */
			int block_width;
			bool latch = true;
			
			j = 0 + comp_offset;
			do {
				block_width = 0;
				do {
					block_width++;
				} while (module_set(m_zintSymbol->rows - 1, j + block_width) == module_set(m_zintSymbol->rows - 1, j));
				if(latch == true) {
					/* a bar */
					painter.fillRect(j + xoffset - comp_offset,m_zintSymbol->height,block_width,5,QBrush(m_fgColor));
					latch = false;
				} else {
					/* a space */
					latch = true;
				}
				j += block_width;
			} while (j < 11 + comp_offset);
			painter.fillRect(46 + xoffset,m_zintSymbol->height,1,5,QBrush(m_fgColor));
			painter.fillRect(48 + xoffset,m_zintSymbol->height,1,5,QBrush(m_fgColor));
			latch = true;
			j = 85 + comp_offset;
			do {
				block_width = 0;
				do {
					block_width++;
				} while (module_set(m_zintSymbol->rows - 1, j + block_width) == module_set(m_zintSymbol->rows - 1, j));
				if(latch == true) {
					/* a bar */
					painter.fillRect(j + xoffset - comp_offset,m_zintSymbol->height,block_width,5,QBrush(m_fgColor));
					latch = false;
				} else {
					/* a space */
					latch = true;
				}
				j += block_width;
			} while (j < 96 + comp_offset);
			painter.drawText(xoffset - 7, m_zintSymbol->height + yoffset + 2, 7, 7,Qt::AlignCenter, caption.mid(0,1));
			painter.drawText(96 + xoffset, m_zintSymbol->height + yoffset + 2, 7, 7,Qt::AlignCenter, caption.mid(11,1));
			painter.setFont(fontLarge);
			painter.drawText(11 + xoffset, m_zintSymbol->height + yoffset, 35, 9,Qt::AlignCenter, caption.mid(1,5));
			painter.drawText(49 + xoffset, m_zintSymbol->height + yoffset, 35, 9,Qt::AlignCenter, caption.mid(6,5));
			if(caption.size() == 15) { /* EAN-2 */ painter.drawText(104 + xoffset, addon_text_height, 20, 9,Qt::AlignCenter, caption.mid(13,2)); };
			if(caption.size() == 18) { /* EAN-5 */ painter.drawText(104 + xoffset, addon_text_height, 47, 9,Qt::AlignCenter, caption.mid(13,5)); };
			painter.setFont(fontSmall);
			textdone = true;
		}
		
		if((m_zintSymbol->symbology == BARCODE_UPCE) || (m_zintSymbol->symbology == BARCODE_UPCE_CC)) {
			/* Add bridge and format text for UPC-E */
			painter.fillRect(0 + xoffset,m_zintSymbol->height,1,5,QBrush(m_fgColor));
			painter.fillRect(2 + xoffset,m_zintSymbol->height,1,5,QBrush(m_fgColor));
			painter.fillRect(46 + xoffset,m_zintSymbol->height,1,5,QBrush(m_fgColor));
			painter.fillRect(48 + xoffset,m_zintSymbol->height,1,5,QBrush(m_fgColor));
			painter.fillRect(50 + xoffset,m_zintSymbol->height,1,5,QBrush(m_fgColor));
			painter.drawText(xoffset - 7, m_zintSymbol->height + yoffset + 2, 7, 7,Qt::AlignCenter, caption.mid(0,1));
			painter.drawText(51 + xoffset, m_zintSymbol->height + yoffset + 2, 7, 7,Qt::AlignCenter, caption.mid(7,1));
			painter.setFont(fontLarge);
			painter.drawText(3 + xoffset, m_zintSymbol->height + yoffset, 43, 9,Qt::AlignCenter, caption.mid(1,6));
			if(caption.size() == 11) { /* EAN-2 */ painter.drawText(60 + xoffset, addon_text_height, 20, 9,Qt::AlignCenter, caption.mid(9,2)); };
			if(caption.size() == 14) { /* EAN-2 */ painter.drawText(60 + xoffset, addon_text_height, 47, 9,Qt::AlignCenter, caption.mid(9,5)); };
			painter.setFont(fontSmall);
			textdone = true;
		}
	} /* if (m_hidetext == false) */
	
	if((m_hidetext == false) && (textdone == false)) {
		/* Add text to any other symbol */
		painter.drawText(0, m_zintSymbol->height + yoffset, m_zintSymbol->width, 7, Qt::AlignCenter, caption);
	}
	painter.restore();
}
Example #24
0
void PaperWalletDialog::on_printButton_clicked()
{

    QPrinter printer(QPrinter::HighResolution);
    QPrintDialog *qpd = new QPrintDialog(&printer, this);

    qpd->setPrintRange(QAbstractPrintDialog::AllPages);

    QList<QString> recipientPubKeyHashes;

    if ( qpd->exec() != QDialog::Accepted ) {
        return;
    }

    // Hardcode these values
    printer.setOrientation(QPrinter::Portrait);
    printer.setPaperSize(QPrinter::A4);
    printer.setFullPage(true);

    QPainter painter;
    if (! painter.begin(&printer)) { // failed to open file
        QMessageBox::critical(this, "Printing Error", tr("failed to open file, is it writable?"), QMessageBox::Ok, QMessageBox::Ok);
        return;
    }

    int walletCount = ui->walletCount->currentIndex() + 1;
    int walletsPerPage = 4;

    int pageHeight = printer.pageRect().height() - PAPER_WALLET_PAGE_MARGIN;
    int walletHeight = ui->paperTemplate->height();
    double computedWalletHeight = 0.9 * pageHeight / walletsPerPage;
    double scale = computedWalletHeight / walletHeight;
    double walletPadding = pageHeight * 0.05 / (walletsPerPage - 1) / scale;

    QRegion walletRegion = QRegion(ui->paperTemplate->x(), ui->paperTemplate->y(),
    ui->paperTemplate->width(), ui->paperTemplate->height());
        painter.scale(scale, scale);

    for(int i = 0; i < walletCount; i++) {

        QPoint point = QPoint(PAPER_WALLET_PAGE_MARGIN, (PAPER_WALLET_PAGE_MARGIN / 2) + ( i % walletsPerPage ) * (walletHeight + walletPadding));
        this->render(&painter, point, walletRegion);
        recipientPubKeyHashes.append(ui->addressText->text());

        if ( i % walletsPerPage == ( walletsPerPage - 1 ) ) {

            printer.newPage();

        }

        this->on_getNewAddress_clicked();

    }

    painter.end();

#ifdef ENABLE_WALLET
    QStringList formatted;

    WalletModelTransaction *tx;
    while( true ) {
        bool ok;

        // Ask for an amount to send to each paper wallet. It might be better to try to use the BitcoinAmountField, but this works fine.
        double amountInput = QInputDialog::getDouble(this, tr("Load Paper Wallets"), tr("The paper wallet printing process has begun.<br/>Please wait for the wallets to print completely and verify that everything printed correctly.<br/>Check for misalignments, ink bleeding, smears, or anything else that could make the private keys unreadable.<br/>Now, enter the number of ARG you wish to send to each wallet:"), 0, 0, 2147483647, 8, &ok);

        if(!ok) {
            return;
        }


        WalletModel::UnlockContext ctx(this->model->requestUnlock());
        if(!ctx.isValid())
        {
            return;
        }

        QList<SendCoinsRecipient> recipients;
        quint64 amount = (quint64) ( amountInput * COIN );
        foreach(const QString &dest, recipientPubKeyHashes)
        {

            recipients.append(SendCoinsRecipient(dest,tr("Paper wallet %1").arg(dest), amount,""));
            formatted.append(tr("<b>%1</b> to Paper Wallet <span style='font-family: monospace;'>%2</span>").arg(QString::number(amountInput, 'f', 8), GUIUtil::HtmlEscape(dest)));

        }

        tx = new WalletModelTransaction(recipients);

        WalletModel::SendCoinsReturn prepareStatus;
        if (this->model->getOptionsModel()->getCoinControlFeatures()) // coin control enabled
            prepareStatus = this->model->prepareTransaction(*tx, CoinControlDialog::coinControl);
        else
            prepareStatus = this->model->prepareTransaction(*tx);

        if (prepareStatus.status == WalletModel::InvalidAddress) {
            QMessageBox::critical(this, tr("Send Coins"), tr("The recipient address is not valid, please recheck."), QMessageBox::Ok, QMessageBox::Ok);
        } else if (prepareStatus.status == WalletModel::InvalidAmount) {
            QMessageBox::critical(this, tr("Send Coins"), tr("The amount to pay must be larger than 0"), QMessageBox::Ok, QMessageBox::Ok);
        } else if (prepareStatus.status == WalletModel::AmountExceedsBalance) {
            QMessageBox::critical(this, tr("Send Coins"), tr("The amount exceeds your balance."), QMessageBox::Ok, QMessageBox::Ok);
        } else if (prepareStatus.status == WalletModel::AmountWithFeeExceedsBalance) {
            QMessageBox::critical(this, tr("Send Coins"), tr("The total exceeds your balance when the transaction fee is included"), QMessageBox::Ok, QMessageBox::Ok);
        } else if (prepareStatus.status == WalletModel::DuplicateAddress) {
            QMessageBox::critical(this, tr("Send Coins"), tr("Duplicate address found, can only send to each address once per send operation."), QMessageBox::Ok, QMessageBox::Ok);
        } else if (prepareStatus.status == WalletModel::TransactionCreationFailed) {
            QMessageBox::critical(this, tr("Send Coins"), tr("Transaction creation failed!"), QMessageBox::Ok, QMessageBox::Ok);
        } else if (prepareStatus.status == WalletModel::OK) {
            break;
        } else {
            delete tx;
            return;
        }

    }
Example #25
0
void MaGraphOverview::drawOverview(QPainter &p) {
    if (displaySettings->orientation == MaGraphOverviewDisplaySettings::FromTopToBottom) {
        // transform coordinate system
        p.translate( 0, height());
        p.scale(1, -1);
    }

    p.fillRect(cachedConsensus.rect(), Qt::white);

    if (editor->getAlignmentLen() == 0) {
        return;
    }

    p.setPen(displaySettings->color);
    p.setBrush(displaySettings->color);

    if (graphCalculationTaskRunner.getResult().isEmpty() && !editor->isAlignmentEmpty() && !isBlocked) {
        sl_drawGraph();
        return;
    }

    QPolygonF resultPolygon = graphCalculationTaskRunner.getResult();
    if (!editor->isAlignmentEmpty() && resultPolygon.last().x() != width()) {
        sl_drawGraph();
        return;
    }

    // area graph
    if (displaySettings->type == MaGraphOverviewDisplaySettings::Area) {
        p.drawPolygon( resultPolygon );
    }

    // line graph
    if (displaySettings->type == MaGraphOverviewDisplaySettings::Line) {
        p.drawPolyline( resultPolygon );
    }

    // hystogram
    if (displaySettings->type == MaGraphOverviewDisplaySettings::Hystogram) {
        int size = graphCalculationTaskRunner.getResult().size();
        for (int i = 0; i < size; i++) {
            const QPointF point = resultPolygon.at(i);
            QPointF nextPoint;
            if (i != size - 1) {
                nextPoint = resultPolygon.at(i + 1);
            } else {
                nextPoint = QPointF(width(), point.y());
            }

            p.drawRect( point.x(), point.y(),
                        static_cast<int>(nextPoint.x() - point.x()) - 2 * (width() > 2 * size),
                        height() - point.y());
        }
    }

    // gray frame
    p.setPen(Qt::gray);
    p.setBrush(Qt::transparent);
    p.drawRect( rect().adjusted( 0, (displaySettings->orientation == MaGraphOverviewDisplaySettings::FromTopToBottom),
                                 -1, -1 * (displaySettings->orientation == MaGraphOverviewDisplaySettings::FromBottomToTop)));

}
Example #26
0
void QgsMapRenderer::render( QPainter* painter, double* forceWidthScale )
{
  //Lock render method for concurrent threads (e.g. from globe)
  QMutexLocker renderLock( &mRenderMutex );

  //flag to see if the render context has changed
  //since the last time we rendered. If it hasnt changed we can
  //take some shortcuts with rendering
  bool mySameAsLastFlag = true;

  QgsDebugMsg( "========== Rendering ==========" );

  if ( mExtent.isEmpty() )
  {
    QgsDebugMsg( "empty extent... not rendering" );
    return;
  }

  if ( mSize.width() == 1 && mSize.height() == 1 )
  {
    QgsDebugMsg( "size 1x1... not rendering" );
    return;
  }

  QPaintDevice* thePaintDevice = painter->device();
  if ( !thePaintDevice )
  {
    return;
  }

  // wait
  if ( mDrawing )
  {
    QgsDebugMsg( "already rendering" );
    QCoreApplication::processEvents();
  }

  if ( mDrawing )
  {
    QgsDebugMsg( "still rendering - skipping" );
    return;
  }

  mDrawing = true;

  const QgsCoordinateTransform *ct;

#ifdef QGISDEBUG
  QgsDebugMsg( "Starting to render layer stack." );
  QTime renderTime;
  renderTime.start();
#endif

  if ( mOverview )
    mRenderContext.setDrawEditingInformation( !mOverview );

  mRenderContext.setPainter( painter );
  mRenderContext.setCoordinateTransform( 0 );
  //this flag is only for stopping during the current rendering progress,
  //so must be false at every new render operation
  mRenderContext.setRenderingStopped( false );

  // set selection color
  QgsProject* prj = QgsProject::instance();
  int myRed = prj->readNumEntry( "Gui", "/SelectionColorRedPart", 255 );
  int myGreen = prj->readNumEntry( "Gui", "/SelectionColorGreenPart", 255 );
  int myBlue = prj->readNumEntry( "Gui", "/SelectionColorBluePart", 0 );
  int myAlpha = prj->readNumEntry( "Gui", "/SelectionColorAlphaPart", 255 );
  mRenderContext.setSelectionColor( QColor( myRed, myGreen, myBlue, myAlpha ) );

  //calculate scale factor
  //use the specified dpi and not those from the paint device
  //because sometimes QPainter units are in a local coord sys (e.g. in case of QGraphicsScene)
  double sceneDpi = mScaleCalculator->dpi();
  double scaleFactor = 1.0;
  if ( mOutputUnits == QgsMapRenderer::Millimeters )
  {
    if ( forceWidthScale )
    {
      scaleFactor = *forceWidthScale;
    }
    else
    {
      scaleFactor = sceneDpi / 25.4;
    }
  }
  double rasterScaleFactor = ( thePaintDevice->logicalDpiX() + thePaintDevice->logicalDpiY() ) / 2.0 / sceneDpi;
  if ( mRenderContext.rasterScaleFactor() != rasterScaleFactor )
  {
    mRenderContext.setRasterScaleFactor( rasterScaleFactor );
    mySameAsLastFlag = false;
  }
  if ( mRenderContext.scaleFactor() != scaleFactor )
  {
    mRenderContext.setScaleFactor( scaleFactor );
    mySameAsLastFlag = false;
  }
  if ( mRenderContext.rendererScale() != mScale )
  {
    //add map scale to render context
    mRenderContext.setRendererScale( mScale );
    mySameAsLastFlag = false;
  }
  if ( mLastExtent != mExtent )
  {
    mLastExtent = mExtent;
    mySameAsLastFlag = false;
  }

  mRenderContext.setLabelingEngine( mLabelingEngine );
  if ( mLabelingEngine )
    mLabelingEngine->init( this );

  // know we know if this render is just a repeat of the last time, we
  // can clear caches if it has changed
  if ( !mySameAsLastFlag )
  {
    //clear the cache pixmap if we changed resolution / extent
    QSettings mySettings;
    if ( mySettings.value( "/qgis/enable_render_caching", false ).toBool() )
    {
      QgsMapLayerRegistry::instance()->clearAllLayerCaches();
    }
  }

  // render all layers in the stack, starting at the base
  QListIterator<QString> li( mLayerSet );
  li.toBack();

  QgsRectangle r1, r2;

  while ( li.hasPrevious() )
  {
    if ( mRenderContext.renderingStopped() )
    {
      break;
    }

    // Store the painter in case we need to swap it out for the
    // cache painter
    QPainter * mypContextPainter = mRenderContext.painter();
    // Flattened image for drawing when a blending mode is set
    QImage * mypFlattenedImage = 0;

    QString layerId = li.previous();

    QgsDebugMsg( "Rendering at layer item " + layerId );

    // This call is supposed to cause the progress bar to
    // advance. However, it seems that updating the progress bar is
    // incompatible with having a QPainter active (the one that is
    // passed into this function), as Qt produces a number of errors
    // when try to do so. I'm (Gavin) not sure how to fix this, but
    // added these comments and debug statement to help others...
    QgsDebugMsg( "If there is a QPaintEngine error here, it is caused by an emit call" );

    //emit drawingProgress(myRenderCounter++, mLayerSet.size());
    QgsMapLayer *ml = QgsMapLayerRegistry::instance()->mapLayer( layerId );

    if ( !ml )
    {
      QgsDebugMsg( "Layer not found in registry!" );
      continue;
    }

    QgsDebugMsg( QString( "layer %1:  minscale:%2  maxscale:%3  scaledepvis:%4  extent:%5  blendmode:%6" )
                 .arg( ml->name() )
                 .arg( ml->minimumScale() )
                 .arg( ml->maximumScale() )
                 .arg( ml->hasScaleBasedVisibility() )
                 .arg( ml->extent().toString() )
                 .arg( ml->blendMode() )
               );

    if ( mRenderContext.useAdvancedEffects() )
    {
      // Set the QPainter composition mode so that this layer is rendered using
      // the desired blending mode
      mypContextPainter->setCompositionMode( ml->blendMode() );
    }

    if ( !ml->hasScaleBasedVisibility() || ( ml->minimumScale() <= mScale && mScale < ml->maximumScale() ) || mOverview )
    {
      connect( ml, SIGNAL( drawingProgress( int, int ) ), this, SLOT( onDrawingProgress( int, int ) ) );

      //
      // Now do the call to the layer that actually does
      // the rendering work!
      //

      bool split = false;

      if ( hasCrsTransformEnabled() )
      {
        r1 = mExtent;
        split = splitLayersExtent( ml, r1, r2 );
        ct = transformation( ml );
        mRenderContext.setExtent( r1 );
        QgsDebugMsg( "  extent 1: " + r1.toString() );
        QgsDebugMsg( "  extent 2: " + r2.toString() );
        if ( !r1.isFinite() || !r2.isFinite() ) //there was a problem transforming the extent. Skip the layer
        {
          continue;
        }
      }
      else
      {
        ct = NULL;
      }

      mRenderContext.setCoordinateTransform( ct );

      //decide if we have to scale the raster
      //this is necessary in case QGraphicsScene is used
      bool scaleRaster = false;
      QgsMapToPixel rasterMapToPixel;
      QgsMapToPixel bk_mapToPixel;

      if ( ml->type() == QgsMapLayer::RasterLayer && qAbs( rasterScaleFactor - 1.0 ) > 0.000001 )
      {
        scaleRaster = true;
      }

      // Force render of layers that are being edited
      // or if there's a labeling engine that needs the layer to register features
      if ( ml->type() == QgsMapLayer::VectorLayer )
      {
        QgsVectorLayer* vl = qobject_cast<QgsVectorLayer *>( ml );
        if ( vl->isEditable() ||
             ( mRenderContext.labelingEngine() && mRenderContext.labelingEngine()->willUseLayer( vl ) ) )
        {
          ml->setCacheImage( 0 );
        }
      }

      QSettings mySettings;
      bool useRenderCaching = false;
      if ( ! split )//render caching does not yet cater for split extents
      {
        if ( mySettings.value( "/qgis/enable_render_caching", false ).toBool() )
        {
          useRenderCaching = true;
          if ( !mySameAsLastFlag || ml->cacheImage() == 0 )
          {
            QgsDebugMsg( "Caching enabled but layer redraw forced by extent change or empty cache" );
            QImage * mypImage = new QImage( mRenderContext.painter()->device()->width(),
                                            mRenderContext.painter()->device()->height(), QImage::Format_ARGB32 );
            if ( mypImage->isNull() )
            {
              QgsDebugMsg( "insufficient memory for image " + QString::number( mRenderContext.painter()->device()->width() ) + "x" + QString::number( mRenderContext.painter()->device()->height() ) );
              emit drawError( ml );
              painter->end(); // drawError is not caught by anyone, so we end painting to notify caller
              return;
            }
            mypImage->fill( 0 );
            ml->setCacheImage( mypImage ); //no need to delete the old one, maplayer does it for you
            QPainter * mypPainter = new QPainter( ml->cacheImage() );
            // Changed to enable anti aliasing by default in QGIS 1.7
            if ( mySettings.value( "/qgis/enable_anti_aliasing", true ).toBool() )
            {
              mypPainter->setRenderHint( QPainter::Antialiasing );
            }
            mRenderContext.setPainter( mypPainter );
          }
          else if ( mySameAsLastFlag )
          {
            //draw from cached image
            QgsDebugMsg( "Caching enabled --- drawing layer from cached image" );
            mypContextPainter->drawImage( 0, 0, *( ml->cacheImage() ) );
            disconnect( ml, SIGNAL( drawingProgress( int, int ) ), this, SLOT( onDrawingProgress( int, int ) ) );
            //short circuit as there is nothing else to do...
            continue;
          }
        }
      }

      // If we are drawing with an alternative blending mode then we need to render to a separate image
      // before compositing this on the map. This effectively flattens the layer and prevents
      // blending occuring between objects on the layer
      // (this is not required for raster layers or when layer caching is enabled, since that has the same effect)
      bool flattenedLayer = false;
      if (( mRenderContext.useAdvancedEffects() ) && ( ml->type() == QgsMapLayer::VectorLayer ) )
      {
        QgsVectorLayer* vl = qobject_cast<QgsVectorLayer *>( ml );
        if (( !useRenderCaching )
            && (( vl->blendMode() != QPainter::CompositionMode_SourceOver )
                || ( vl->featureBlendMode() != QPainter::CompositionMode_SourceOver )
                || ( vl->layerTransparency() != 0 ) ) )
        {
          flattenedLayer = true;
          mypFlattenedImage = new QImage( mRenderContext.painter()->device()->width(),
                                          mRenderContext.painter()->device()->height(), QImage::Format_ARGB32 );
          if ( mypFlattenedImage->isNull() )
          {
            QgsDebugMsg( "insufficient memory for image " + QString::number( mRenderContext.painter()->device()->width() ) + "x" + QString::number( mRenderContext.painter()->device()->height() ) );
            emit drawError( ml );
            painter->end(); // drawError is not caught by anyone, so we end painting to notify caller
            return;
          }
          mypFlattenedImage->fill( 0 );
          QPainter * mypPainter = new QPainter( mypFlattenedImage );
          if ( mySettings.value( "/qgis/enable_anti_aliasing", true ).toBool() )
          {
            mypPainter->setRenderHint( QPainter::Antialiasing );
          }
          mypPainter->scale( rasterScaleFactor,  rasterScaleFactor );
          mRenderContext.setPainter( mypPainter );
        }
      }

      // Per feature blending mode
      if (( mRenderContext.useAdvancedEffects() ) && ( ml->type() == QgsMapLayer::VectorLayer ) )
      {
        QgsVectorLayer* vl = qobject_cast<QgsVectorLayer *>( ml );
        if ( vl->featureBlendMode() != QPainter::CompositionMode_SourceOver )
        {
          // set the painter to the feature blend mode, so that features drawn
          // on this layer will interact and blend with each other
          mRenderContext.painter()->setCompositionMode( vl->featureBlendMode() );
        }
      }

      if ( scaleRaster )
      {
        bk_mapToPixel = mRenderContext.mapToPixel();
        rasterMapToPixel = mRenderContext.mapToPixel();
        rasterMapToPixel.setMapUnitsPerPixel( mRenderContext.mapToPixel().mapUnitsPerPixel() / rasterScaleFactor );
        rasterMapToPixel.setYMaximum( mSize.height() * rasterScaleFactor );
        mRenderContext.setMapToPixel( rasterMapToPixel );
        mRenderContext.painter()->save();
        mRenderContext.painter()->scale( 1.0 / rasterScaleFactor, 1.0 / rasterScaleFactor );
      }

      if ( !ml->draw( mRenderContext ) )
      {
        emit drawError( ml );
      }
      else
      {
        QgsDebugMsg( "Layer rendered without issues" );
      }

      if ( split )
      {
        mRenderContext.setExtent( r2 );
        if ( !ml->draw( mRenderContext ) )
        {
          emit drawError( ml );
        }
      }

      if ( scaleRaster )
      {
        mRenderContext.setMapToPixel( bk_mapToPixel );
        mRenderContext.painter()->restore();
      }

      //apply layer transparency for vector layers
      if (( mRenderContext.useAdvancedEffects() ) && ( ml->type() == QgsMapLayer::VectorLayer ) )
      {
        QgsVectorLayer* vl = qobject_cast<QgsVectorLayer *>( ml );
        if ( vl->layerTransparency() != 0 )
        {
          // a layer transparency has been set, so update the alpha for the flattened layer
          // by combining it with the layer transparency
          QColor transparentFillColor = QColor( 0, 0, 0, 255 - ( 255 * vl->layerTransparency() / 100 ) );
          // use destination in composition mode to merge source's alpha with destination
          mRenderContext.painter()->setCompositionMode( QPainter::CompositionMode_DestinationIn );
          mRenderContext.painter()->fillRect( 0, 0, mRenderContext.painter()->device()->width(),
                                              mRenderContext.painter()->device()->height(), transparentFillColor );
        }
      }

      if ( useRenderCaching )
      {
        // composite the cached image into our view and then clean up from caching
        // by reinstating the painter as it was swapped out for caching renders
        delete mRenderContext.painter();
        mRenderContext.setPainter( mypContextPainter );
        //draw from cached image that we created further up
        if ( ml->cacheImage() )
          mypContextPainter->drawImage( 0, 0, *( ml->cacheImage() ) );
      }
      else if ( flattenedLayer )
      {
        // If we flattened this layer for alternate blend modes, composite it now
        delete mRenderContext.painter();
        mRenderContext.setPainter( mypContextPainter );
        mypContextPainter->save();
        mypContextPainter->scale( 1.0 / rasterScaleFactor, 1.0 / rasterScaleFactor );
        mypContextPainter->drawImage( 0, 0, *( mypFlattenedImage ) );
        mypContextPainter->restore();
        delete mypFlattenedImage;
        mypFlattenedImage = 0;
      }

      disconnect( ml, SIGNAL( drawingProgress( int, int ) ), this, SLOT( onDrawingProgress( int, int ) ) );
    }
Example #27
0
void PlotFrame::on_printToolButton_clicked(void)
{
    if (this->plotScene->items().count() <= 0)
    {
        QMessageBox::information(this, tr("Impression impossible"),
                                 tr("Aucune courbe à imprimer"));
        return;
    }

    // Display printing options dialog
    PlotPrintDialog ppd;
    if (ppd.exec() == QDialog::Rejected)
        return;

    // Printing options
    switch (ppd.getPrintType())
    {
        case PlotPrintDialog::printing:
        {
            // Printer configuration
            QPrinter printer(ppd.printerMode());
            printer.setPaperSize(ppd.paperSize());
            printer.setOrientation(ppd.paperOrientation());

            // Printer dialog to choose a printer
            QPrintDialog printDialog(&printer);
            if (printDialog.exec() == QDialog::Rejected)
            {
                QMessageBox::information(this, tr("Impression interrompue"),
                             tr("L'impression à correctement été interrompue"));
                break;
            }

            // Printing ...
            QPainter painter;
            painter.setRenderHint(QPainter::Antialiasing);
            painter.begin(&printer);

            if(ppd.printWithScales())
            {
                // Enlever les boutons d'options
                QRect rectLayoutToolButtons = this->ui->toolButtonsHLayout->geometry();
                this->ui->toolButtonsHLayout->setGeometry(QRect(0, 0, 0, 0));

                double xscale = printer.pageRect().width() / double(this->width());
                double yscale = printer.pageRect().height() / double(this->height());
                double scale = qMin(xscale, yscale);
                painter.translate(printer.paperRect().x() + printer.pageRect().width() / 2,
                                  printer.paperRect().y() + printer.pageRect().height() / 2);
                painter.scale(scale, scale);
                painter.translate(-width() / 2, -height() / 2);

                /* Modifie flag pour ne pas imprimer la couleur de
                 * fond des widgets parnets et enfants */
                this->render(&painter, QPoint(), QRegion(),
                             QWidget::DrawChildren);

                // Restore layout geometry
                this->ui->toolButtonsHLayout->setGeometry(rectLayoutToolButtons);
            }
            else
            {
                if (ppd.printCurrentView())
                    this->plotView->render(&painter, QRectF(), QRect(),
                                           Qt::IgnoreAspectRatio);
                else
                    this->plotScene->render(&painter, QRectF(), QRectF(),
                                            Qt::IgnoreAspectRatio);
            }

            painter.end();
            break;
        }
        case PlotPrintDialog::picture:
        {
            QString fileName = QFileDialog::getSaveFileName(
                        this, tr("Sauvegarder un image du graphique"),
                        QDir::homePath(), tr("Images (*.png *.xpm *.jpg)"));
            QFileInfo fileInfo(fileName);

            if (ppd.printWithScales())
            {
                // Enlever les boutons d'options
                QRect rectLayoutToolButtons = this->ui->toolButtonsHLayout->geometry();
                this->ui->toolButtonsHLayout->setGeometry(QRect(0, 0, 0, 0));

                QPixmap pixmap(this->size());
                this->render(&pixmap);

                // Restore layout geometry
                this->ui->toolButtonsHLayout->setGeometry(rectLayoutToolButtons);

                pixmap.save(fileInfo.absoluteFilePath(),
                            fileInfo.suffix().toStdString().c_str(),
                            ppd.pictureQuality());
            }
            else
            {
                if (ppd.printCurrentView()) // Marche
                {
                    QImage image(QSize(1920, 1080), QImage::Format_ARGB32);
                    QPainter painter;
                    painter.begin(&image);
                    painter.setRenderHint(QPainter::Antialiasing);

                    this->plotView->render(&painter, QRectF(), QRect(),
                                           Qt::IgnoreAspectRatio);
                    image.save(fileInfo.absoluteFilePath(),
                               fileInfo.suffix().toStdString().c_str(),
                               ppd.pictureQuality());
                    painter.end();
                }
                else
                {
                    QImage image(QSize(1920, 1080), QImage::Format_ARGB32);
                    QPainter painter;
                    painter.begin(&image);
                    painter.setRenderHint(QPainter::Antialiasing);



                    this->plotScene->render(&painter, QRectF(), QRectF(),
                                            Qt::IgnoreAspectRatio);

                    image = image.mirrored();
                    image.save(fileInfo.absoluteFilePath(),
                               fileInfo.suffix().toStdString().c_str(),
                               ppd.pictureQuality());
                    painter.end();
                }
            }

            break;
        }
        default:
            QMessageBox::warning(this, tr("Impression impossible"),
                                 tr("Mode d'impression non supporté"));
            break;
    }
}
Example #28
0
//drawing:
void G_segment::draw(QPainter &p, const G_drawstyle &d, bool selected)
{
  QRect r = p.window();

  if(!inRect(r)) return;

  G_point tmp1, tmp2;
  
  if(fabs(p1.getX()) < DRAW_MAX && fabs(p1.getY()) < DRAW_MAX) {
    tmp1 = p1;
  }
  else {
    tmp1 = getNearestPoint(G_point(0, 0));
    tmp1 += (p1 - tmp1) * (DRAW_MAX) / (p1 - tmp1).length();
  }

  if(fabs(p2.getX()) < DRAW_MAX && fabs(p2.getY()) < DRAW_MAX) {
    tmp2 = p2;
  }
  else {
    tmp2 = getNearestPoint(G_point(0, 0));
    tmp2 += (p2 - tmp2) * (DRAW_MAX) / (p2 - tmp2).length();
  }

  //Now Draw!

  if(/*p.device()->isExtDev() ||*/ p.hasViewXForm()) { //draw at higher accuracy to a printer
    tmp1 *= 8.;
    tmp2 *= 8.;
    p.scale(0.125, .125);
    
    int w = d.getPen().width() * 8;
    if(w == 0) w = 2;
    //if(!p.device()->isExtDev()) w = (d.getPen().width() == 0 ? 4 : 4 * d.getPen().width());

    p.setPen(QPen(d.getPen().color(), w, d.getPen().style()));
    p.drawLine(tmp1.toQPoint(), tmp2.toQPoint());

    p.scale(8, 8);

    return;
  }

  if(selected && KSegView::getSelectType() == KSegView::BORDER_SELECT) {
    int width = d.getPen().width() ? d.getPen().width() + 3 : 4;

    p.setPen(QPen(G_drawstyle::getBorderColor(d.getPen().color()), width));

    p.drawLine(tmp1.toQPoint(), tmp2.toQPoint());
    
  }

  p.setPen(d.getPen());
  if(selected && KSegView::getSelectType() == KSegView::BLINKING_SELECT) {
    QColor c(QTime::currentTime().msec() * 17, 255, 255, QColor::Hsv);

    p.setPen(QPen(c, d.getPen().width(), d.getPen().style()));
  }

  p.drawLine(tmp1.toQPoint(), tmp2.toQPoint());

  return;
	     
}
Example #29
0
void PagePainter::paintPageOnPainter( const KPDFPage * page, int id, int flags,
    QPainter * destPainter, const QRect & limits, int width, int height )
{
    QPixmap * pixmap = 0;

    // if a pixmap is present for given id, use it
    if ( page->m_pixmaps.contains( id ) )
        pixmap = page->m_pixmaps[ id ];

    // else find the closest match using pixmaps of other IDs (great optim!)
    else if ( !page->m_pixmaps.isEmpty() && width != -1 )
    {
        int minDistance = -1;
        QMap< int,QPixmap * >::const_iterator it = page->m_pixmaps.begin(), end = page->m_pixmaps.end();
        for ( ; it != end; ++it )
        {
            int pixWidth = (*it)->width(),
                distance = pixWidth > width ? pixWidth - width : width - pixWidth;
            if ( minDistance == -1 || distance < minDistance )
            {
                pixmap = *it;
                minDistance = distance;
            }
        }
    }

    // if have no pixmap, draw blank page with gray cross and exit
    if ( !pixmap )
    {
        QColor color = Qt::white;
        if ( KpdfSettings::changeColors() )
        {
            switch ( KpdfSettings::renderMode() )
            {
                case KpdfSettings::EnumRenderMode::Inverted:
                    color = Qt::black;
                    break;
                case KpdfSettings::EnumRenderMode::Paper:
                    color = KpdfSettings::paperColor();
                    break;
                case KpdfSettings::EnumRenderMode::Recolor:
                    color = KpdfSettings::recolorBackground();
                    break;
                default: ;
            }
        }
        destPainter->fillRect( limits, color );

        // draw a cross (to  that the pixmap as not yet been loaded)
        // helps a lot on pages that take much to render
        destPainter->setPen( Qt::gray );
        destPainter->drawLine( 0, 0, width-1, height-1 );
        destPainter->drawLine( 0, height-1, width-1, 0 );
        // idea here: draw a hourglass (or kpdf icon :-) on top-left corner
        return;
    }

    // find out what to paint over the pixmap (manipulations / overlays)
    bool paintAccessibility = (flags & Accessibility) && KpdfSettings::changeColors() && (KpdfSettings::renderMode() != KpdfSettings::EnumRenderMode::Paper);
    bool paintHighlights = (flags & Highlights) && !page->m_highlights.isEmpty();
    bool enhanceLinks = (flags & EnhanceLinks) && KpdfSettings::highlightLinks();
    bool enhanceImages = (flags & EnhanceImages) && KpdfSettings::highlightImages();
    // check if there are really some highlightRects to paint
    if ( paintHighlights )
    {
        // precalc normalized 'limits rect' for intersection
        double nXMin = (double)limits.left() / (double)width,
               nXMax = (double)limits.right() / (double)width,
               nYMin = (double)limits.top() / (double)height,
               nYMax = (double)limits.bottom() / (double)height;
        // if no rect intersects limits, disable paintHighlights
        paintHighlights = false;
        QValueList< HighlightRect * >::const_iterator hIt = page->m_highlights.begin(), hEnd = page->m_highlights.end();
        for ( ; hIt != hEnd; ++hIt )
        {
            if ( (*hIt)->intersects( nXMin, nYMin, nXMax, nYMax ) )
            {
                paintHighlights = true;
                break;
            }
        }
    }

    // use backBuffer if 'pixmap direct manipulation' is needed
    bool backBuffer = paintAccessibility || paintHighlights;
    QPixmap * backPixmap = 0;
    QPainter * p = destPainter;
    if ( backBuffer )
    {
        // let's paint using a buffered painter
        backPixmap = new QPixmap( limits.width(), limits.height() );
        p = new QPainter( backPixmap );
        p->translate( -limits.left(), -limits.top() );
    }

    // 1. fast blit the pixmap if it has the right size..
    if ( pixmap->width() == width && pixmap->height() == height )
        p->drawPixmap( limits.topLeft(), *pixmap, limits );
    // ..else set a scale matrix to the painter and paint a quick 'zoomed' pixmap
    else
    {
        p->save();
        // TODO paint only the needed part (note: hope that Qt4 transforms are faster)
        p->scale( width / (double)pixmap->width(), height / (double)pixmap->height() );
        p->drawPixmap( 0,0, *pixmap, 0,0, pixmap->width(), pixmap->height() );
        p->restore();
    }

    // 2. mangle pixmap: convert it to 32-bit qimage and perform pixel-level manipulations
    if ( backBuffer )
    {
        QImage backImage = backPixmap->convertToImage();
        // 2.1. modify pixmap following accessibility settings
        if ( paintAccessibility )
        {
            switch ( KpdfSettings::renderMode() )
            {
                case KpdfSettings::EnumRenderMode::Inverted:
                    // Invert image pixels using QImage internal function
                    backImage.invertPixels(false);
                    break;
                case KpdfSettings::EnumRenderMode::Recolor:
                    // Recolor image using KImageEffect::flatten with dither:0
                    KImageEffect::flatten( backImage, KpdfSettings::recolorForeground(), KpdfSettings::recolorBackground() );
                    break;
                case KpdfSettings::EnumRenderMode::BlackWhite:
                    // Manual Gray and Contrast
                    unsigned int * data = (unsigned int *)backImage.bits();
                    int val, pixels = backImage.width() * backImage.height(),
                        con = KpdfSettings::bWContrast(), thr = 255 - KpdfSettings::bWThreshold();
                    for( int i = 0; i < pixels; ++i )
                    {
                        val = qGray( data[i] );
                        if ( val > thr )
                            val = 128 + (127 * (val - thr)) / (255 - thr);
                        else if ( val < thr )
                            val = (128 * val) / thr;
                        if ( con > 2 )
                        {
                            val = con * ( val - thr ) / 2 + thr;
                            if ( val > 255 )
                                val = 255;
                            else if ( val < 0 )
                                val = 0;
                        }
                        data[i] = qRgba( val, val, val, 255 );
                    }
                    break;
            }
        }
        // 2.2. highlight rects in page
        if ( paintHighlights )
        {
            // draw highlights that are inside the 'limits' paint region
            QValueList< HighlightRect * >::const_iterator hIt = page->m_highlights.begin(), hEnd = page->m_highlights.end();
            for ( ; hIt != hEnd; ++hIt )
            {
                HighlightRect * r = *hIt;
                QRect highlightRect = r->geometry( width, height );
                if ( highlightRect.isValid() && highlightRect.intersects( limits ) )
                {
                    // find out the rect to highlight on pixmap
                    highlightRect = highlightRect.intersect( limits );
                    highlightRect.moveBy( -limits.left(), -limits.top() );

                    // highlight composition (product: highlight color * destcolor)
                    unsigned int * data = (unsigned int *)backImage.bits();
                    int val, newR, newG, newB,
                        rh = r->color.red(),
                        gh = r->color.green(),
                        bh = r->color.blue(),
                        offset = highlightRect.top() * backImage.width();
                    for( int y = highlightRect.top(); y <= highlightRect.bottom(); ++y )
                    {
                        for( int x = highlightRect.left(); x <= highlightRect.right(); ++x )
                        {
                            val = data[ x + offset ];
                            newR = (qRed(val) * rh) / 255;
                            newG = (qGreen(val) * gh) / 255;
                            newB = (qBlue(val) * bh) / 255;
                            data[ x + offset ] = qRgba( newR, newG, newB, 255 );
                        }
                        offset += backImage.width();
                    }
                }
            }
        }
        backPixmap->convertFromImage( backImage );
    }

    // 3. visually enchance links and images if requested
    if ( enhanceLinks || enhanceImages )
    {
        QColor normalColor = QApplication::palette().active().highlight();
        QColor lightColor = normalColor.light( 140 );
        // enlarging limits for intersection is like growing the 'rectGeometry' below
        QRect limitsEnlarged = limits;
        limitsEnlarged.addCoords( -2, -2, 2, 2 );
        // draw rects that are inside the 'limits' paint region as opaque rects
        QValueList< ObjectRect * >::const_iterator lIt = page->m_rects.begin(), lEnd = page->m_rects.end();
        for ( ; lIt != lEnd; ++lIt )
        {
            ObjectRect * rect = *lIt;
            if ( (enhanceLinks && rect->objectType() == ObjectRect::Link) ||
                 (enhanceImages && rect->objectType() == ObjectRect::Image) )
            {
                QRect rectGeometry = rect->geometry( width, height );
                if ( rectGeometry.intersects( limitsEnlarged ) )
                {
                    // expand rect and draw inner border
                    rectGeometry.addCoords( -1,-1,1,1 );
                    p->setPen( lightColor );
                    p->drawRect( rectGeometry );
                    // expand rect to draw outer border
                    rectGeometry.addCoords( -1,-1,1,1 );
                    p->setPen( normalColor );
                    p->drawRect( rectGeometry );
                }
            }
        }
    }

    // 4. if was backbuffering, copy the backPixmap to destination
    if ( backBuffer )
    {
        delete p;
        destPainter->drawPixmap( limits.left(), limits.top(), *backPixmap );
        delete backPixmap;
    }
}
void Map::show(QPainter &painter, int minX, int maxX)
{
    static QPointF polygonPoints[4];
    painter.setFont(font);
    roadBrush.setColor(Qt::darkGray);
    painter.setBrush(roadBrush);
    for(int i = 0; i < points.size() - 1; ++i)
    {
        polygonPoints[0].setX((points[i].x) * 100);
        polygonPoints[0].setY((points[i].y + boxWidth) * 100);
        polygonPoints[1].setX((points[i].x) * 100);
        polygonPoints[1].setY((points[i].y - boxWidth) * 100);
        polygonPoints[2].setX(points[i + 1].x * 100);
        polygonPoints[2].setY((points[i + 1].y - boxWidth) * 100);
        polygonPoints[3].setX(points[i + 1].x * 100);
        polygonPoints[3].setY((points[i + 1].y + boxWidth) * 100);
        if((polygonPoints[2].x() >= minX) && (polygonPoints[0].x() <= maxX))
        {
            painter.drawPolygon(polygonPoints, 4);
        }
    }

    leftPopulation -> show(painter);
    if(leftPopulation -> getPopulationType())
    {
        rightPopulation -> show(painter);
    }

    if(showInfo)
    {
        if(leftPopulation -> getPopulationType())
        {
            QFont tmpFont;
            tmpFont.setPixelSize(40);
            painter.setFont(tmpFont);
            for(int i = 0; i < leftPopulation -> getSize(); ++i)
            {
                Vehicle *tmpVehicle = leftPopulation -> getVehicle(i);
                if(tmpVehicle -> alive())
                {
                    painter.translate(tmpVehicle -> GetPosition().x * 100, tmpVehicle -> GetPosition().y * 100);
                    painter.rotate(180.0);
                    painter.scale(-1.0, 1.0);
                    painter.drawText(10, -150, QString::number(i + 1));
                    painter.scale(-1.0, 1.0);
                    painter.rotate(-180.0);
                    painter.translate(-tmpVehicle -> GetPosition().x * 100, -tmpVehicle -> GetPosition().y * 100);
                }
            }

            for(int i = 0; i < rightPopulation -> getSize(); ++i)
            {
                Vehicle *tmpVehicle = rightPopulation -> getVehicle(i);
                if(tmpVehicle -> alive())
                {
                    painter.translate(tmpVehicle -> GetPosition().x * 100, tmpVehicle -> GetPosition().y * 100);
                    painter.rotate(180.0);
                    painter.scale(-1.0, 1.0);
                    painter.drawText(10, -150, QString::number(i + 1));
                    painter.scale(-1.0, 1.0);
                    painter.rotate(-180.0);
                    painter.translate(-tmpVehicle -> GetPosition().x * 100, -tmpVehicle -> GetPosition().y * 100);
                }
            }
        }

        painter.setFont(font);
        painter.setTransform(QTransform(1.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 1.0));
        painter.drawText(10, 100,
                         QString("Score: ") + QString::number(leftPopulation -> getCurrentVehicle() -> getScore(), 'f', 1));
        painter.drawText(10, 150,
                         QString("Generation: ") + QString::number(leftPopulation -> getCurrentGeneration() + 1));
        painter.drawText(10, 200,
                         QString("Test: ") + QString::number(leftPopulation -> getCurrentTest() + 1));
        painter.drawText(10, 250,
                         QString("Best score: ") + QString::number(leftPopulation -> getBestResult(), 'f', 1));
    }
}