Exemple #1
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);
    }
}
static void qwtRenderBackground( QPainter *painter,
    const QRectF &rect, const QWidget *widget )
{
    if ( widget->testAttribute( Qt::WA_StyledBackground ) )
    {
        QStyleOption opt;
        opt.initFrom( widget );
        opt.rect = rect.toAlignedRect();

        widget->style()->drawPrimitive(
            QStyle::PE_Widget, &opt, painter, widget);
    }
    else
    {
        const QBrush brush = 
            widget->palette().brush( widget->backgroundRole() );

        painter->fillRect( rect, brush );
    }
}
Exemple #3
0
void IsometricRenderer::drawGrid(QPainter *painter, const QRectF &rect,
                                 QColor gridColor) const
{
    const int tileWidth = map()->tileWidth();
    const int tileHeight = map()->tileHeight();

    QRect r = rect.toAlignedRect();
    r.adjust(-tileWidth / 2, -tileHeight / 2,
             tileWidth / 2, tileHeight / 2);

    int startX = screenToTileCoords(r.topLeft()).x();
    int startY = screenToTileCoords(r.topRight()).y();
    int endX = screenToTileCoords(r.bottomRight()).x();
    int endY = screenToTileCoords(r.bottomLeft()).y();

    if (!map()->infinite()) {
        startX = qMax(0, startX);
        startY = qMax(0, startY);
        endX = qMin(map()->width(), endX);
        endY = qMin(map()->height(), endY);
    }

    QPen gridPen = makeGridPen(painter->device(), gridColor);
    painter->setPen(gridPen);

    for (int y = startY; y <= endY; ++y) {
        const QPointF start = tileToScreenCoords(startX, y);
        const QPointF end = tileToScreenCoords(endX, y);
        painter->drawLine(start, end);
    }
    for (int x = startX; x <= endX; ++x) {
        const QPointF start = tileToScreenCoords(x, startY);
        const QPointF end = tileToScreenCoords(x, endY);
        painter->drawLine(start, end);
    }
}
Exemple #4
0
void IsometricRenderer::drawTileLayer(QPainter *painter,
                                      const TileLayer *layer,
                                      const QRectF &exposed) const
{
    const int tileWidth = map()->tileWidth();
    const int tileHeight = map()->tileHeight();

    QRect rect = exposed.toAlignedRect();
    if (rect.isNull())
        rect = boundingRect(layer->bounds());

    const QSize maxTileSize = layer->maxTileSize();
    const int extraWidth = maxTileSize.width() - tileWidth;
    const int extraHeight = maxTileSize.height() - tileHeight;
    rect.adjust(-extraWidth, 0, 0, extraHeight);

    // Determine the tile and pixel coordinates to start at
    QPointF tilePos = pixelToTileCoords(rect.x(), rect.y());
    QPoint rowItr = QPoint((int) std::floor(tilePos.x()),
                           (int) std::floor(tilePos.y()));
    QPointF startPos = tileToPixelCoords(rowItr);
    startPos.rx() -= tileWidth / 2;
    startPos.ry() += tileHeight;

    // Compensate for the layer position
    rowItr -= QPoint(layer->x(), layer->y());

    /* Determine in which half of the tile the top-left corner of the area we
     * need to draw is. If we're in the upper half, we need to start one row
     * up due to those tiles being visible as well. How we go up one row
     * depends on whether we're in the left or right half of the tile.
     */
    const bool inUpperHalf = startPos.y() - rect.y() > tileHeight / 2;
    const bool inLeftHalf = rect.x() - startPos.x() < tileWidth / 2;

    if (inUpperHalf) {
        if (inLeftHalf) {
            --rowItr.rx();
            startPos.rx() -= tileWidth / 2;
        } else {
            --rowItr.ry();
            startPos.rx() += tileWidth / 2;
        }
        startPos.ry() -= tileHeight / 2;
    }

    // Determine whether the current row is shifted half a tile to the right
    bool shifted = inUpperHalf ^ inLeftHalf;

    for (int y = startPos.y(); y - tileHeight < rect.bottom();
         y += tileHeight / 2)
    {
        QPoint columnItr = rowItr;

        for (int x = startPos.x(); x < rect.right(); x += tileWidth) {
            if (layer->contains(columnItr)) {
                if (const Tile *tile = layer->tileAt(columnItr)) {
                    const QPixmap &img = tile->image();
                    painter->drawPixmap(x, y - img.height(), img);
                }
            }

            // Advance to the next column
            ++columnItr.rx();
            --columnItr.ry();
        }

        // Advance to the next row
        if (!shifted) {
            ++rowItr.rx();
            startPos.rx() += tileWidth / 2;
            shifted = true;
        } else {
            ++rowItr.ry();
            startPos.rx() -= tileWidth / 2;
            shifted = false;
        }
    }
}
Exemple #5
0
void StaggeredRenderer::drawTileLayer(QPainter *painter,
                                      const TileLayer *layer,
                                      const QRectF &exposed) const
{
    const int tileWidth = map()->tileWidth();
    const int tileHeight = map()->tileHeight();

    QRect rect = exposed.toAlignedRect();
    if (rect.isNull())
        rect = boundingRect(layer->bounds());

    QMargins drawMargins = layer->drawMargins();
    drawMargins.setRight(drawMargins.right() - tileWidth);

    rect.adjust(-drawMargins.right(),
                -drawMargins.bottom(),
                drawMargins.left(),
                drawMargins.top());

    // Determine the tile and pixel coordinates to start at
    QPoint startTile = pixelToTileCoords(rect.x(), rect.y()).toPoint();

    // Compensate for the layer position
    startTile -= layer->position();

    QPoint startPos = tileToPixelCoords(startTile + layer->position()).toPoint();

    /* Determine in which half of the tile the top-left corner of the area we
     * need to draw is. If we're in the upper half, we need to start one row
     * up due to those tiles being visible as well. How we go up one row
     * depends on whether we're in the left or right half of the tile.
     */
    const bool inUpperHalf = startPos.y() - rect.y() > tileHeight / 2;
    const bool inLeftHalf = rect.x() - startPos.x() < tileWidth / 2;

    if (inUpperHalf)
        startTile.ry()--;
    if (inLeftHalf)
        startTile.rx()--;

    startTile.setX(qMax(0, startTile.x()));
    startTile.setY(qMax(0, startTile.y()));

    startPos = tileToPixelCoords(startTile + layer->position()).toPoint();
    startPos.ry() += tileHeight;

    // Odd row shifting is applied in the rendering loop, so un-apply it here
    if ((startTile.y() + layer->y()) % 2)
        startPos.rx() -= tileWidth / 2;

    qDebug() << rect << startTile << startPos << layer->position();

    QTransform baseTransform = painter->transform();

    for (; startPos.y() < rect.bottom() && startTile.y() < layer->height(); startTile.ry()++) {
        QPoint rowTile = startTile;
        QPoint rowPos = startPos;

        if ((startTile.y() + layer->y()) % 2)
            rowPos.rx() += tileWidth / 2;

        for (; rowPos.x() < rect.right() && rowTile.x() < layer->width(); rowTile.rx()++) {
            const Cell &cell = layer->cellAt(rowTile);
            if (cell.isEmpty()) {
                rowPos.rx() += tileWidth;
                continue;
            }

            const QPixmap &img = cell.tile->image();
            const QPoint offset = cell.tile->tileset()->tileOffset();

            qreal m11 = 1;      // Horizontal scaling factor
            qreal m12 = 0;      // Vertical shearing factor
            qreal m21 = 0;      // Horizontal shearing factor
            qreal m22 = 1;      // Vertical scaling factor
            qreal dx = offset.x() + rowPos.x();
            qreal dy = offset.y() + rowPos.y() - img.height();

            if (cell.flippedAntiDiagonally) {
                // Use shearing to swap the X/Y axis
                m11 = 0;
                m12 = 1;
                m21 = 1;
                m22 = 0;

                // Compensate for the swap of image dimensions
                dy += img.height() - img.width();
            }
            if (cell.flippedHorizontally) {
                m11 = -m11;
                m21 = -m21;
                dx += cell.flippedAntiDiagonally ? img.height()
                                                 : img.width();
            }
            if (cell.flippedVertically) {
                m12 = -m12;
                m22 = -m22;
                dy += cell.flippedAntiDiagonally ? img.width()
                                                 : img.height();
            }

            const QTransform transform(m11, m12, m21, m22, dx, dy);
            painter->setTransform(transform * baseTransform);

            painter->drawPixmap(0, 0, img);

            rowPos.rx() += tileWidth;
        }

        startPos.ry() += tileHeight / 2;
    }

    painter->setTransform(baseTransform);
}
bool QAlphaPaintEnginePrivate::fullyContained(const QRectF &rect) const
{
    QRegion r(rect.toAlignedRect());
    return (m_cliprgn.intersected(r) == r);
}
bool QAlphaPaintEnginePrivate::canSeeTroughBackground(bool somethingInRectHasAlpha, const QRectF &rect) const
{
    return somethingInRectHasAlpha && m_dirtyrgn.intersects(rect.toAlignedRect());
}
void HexagonalRenderer::drawGrid(QPainter *painter, const QRectF &exposed,
                                 QColor gridColor) const
{
    QRect rect = exposed.toAlignedRect();
    if (rect.isNull())
        return;

    const RenderParams p(map());

    // Determine the tile and pixel coordinates to start at
    QPoint startTile = screenToTileCoords(rect.topLeft()).toPoint();
    QPoint startPos = tileToScreenCoords(startTile).toPoint();

    /* Determine in which half of the tile the top-left corner of the area we
     * need to draw is. If we're in the upper half, we need to start one row
     * up due to those tiles being visible as well. How we go up one row
     * depends on whether we're in the left or right half of the tile.
     */
    const bool inUpperHalf = rect.y() - startPos.y() < p.sideOffsetY;
    const bool inLeftHalf = rect.x() - startPos.x() < p.sideOffsetX;

    if (inUpperHalf)
        startTile.ry()--;
    if (inLeftHalf)
        startTile.rx()--;

    startTile.setX(qMax(0, startTile.x()));
    startTile.setY(qMax(0, startTile.y()));

    startPos = tileToScreenCoords(startTile).toPoint();

    const QPoint oct[8] = {
        QPoint(0,                           p.tileHeight - p.sideOffsetY),
        QPoint(0,                           p.sideOffsetY),
        QPoint(p.sideOffsetX,               0),
        QPoint(p.tileWidth - p.sideOffsetX, 0),
        QPoint(p.tileWidth,                 p.sideOffsetY),
        QPoint(p.tileWidth,                 p.tileHeight - p.sideOffsetY),
        QPoint(p.tileWidth - p.sideOffsetX, p.tileHeight),
        QPoint(p.sideOffsetX,               p.tileHeight)
    };

    QVector<QLine> lines;
    lines.reserve(8);

    gridColor.setAlpha(128);

    QPen gridPen(gridColor);
    gridPen.setCosmetic(true);
    gridPen.setDashPattern(QVector<qreal>() << 2 << 2);
    painter->setPen(gridPen);

    if (p.staggerX) {
        // Odd row shifting is applied in the rendering loop, so un-apply it here
        if (p.doStaggerX(startTile.x()))
            startPos.ry() -= p.rowHeight;

        for (; startPos.x() <= rect.right() && startTile.x() < map()->width(); startTile.rx()++) {
            QPoint rowTile = startTile;
            QPoint rowPos = startPos;

            if (p.doStaggerX(startTile.x()))
                rowPos.ry() += p.rowHeight;

            for (; rowPos.y() <= rect.bottom() && rowTile.y() < map()->height(); rowTile.ry()++) {
                lines.append(QLine(rowPos + oct[1], rowPos + oct[2]));
                lines.append(QLine(rowPos + oct[2], rowPos + oct[3]));
                lines.append(QLine(rowPos + oct[3], rowPos + oct[4]));

                const bool isStaggered = p.doStaggerX(startTile.x());
                const bool lastRow = rowTile.y() == map()->height() - 1;
                const bool lastColumn = rowTile.x() == map()->width() - 1;
                const bool bottomLeft = rowTile.x() == 0 || (lastRow && isStaggered);
                const bool bottomRight = lastColumn || (lastRow && isStaggered);

                if (bottomRight)
                    lines.append(QLine(rowPos + oct[5], rowPos + oct[6]));
                if (lastRow)
                    lines.append(QLine(rowPos + oct[6], rowPos + oct[7]));
                if (bottomLeft)
                    lines.append(QLine(rowPos + oct[7], rowPos + oct[0]));

                painter->drawLines(lines);
                lines.resize(0);

                rowPos.ry() += p.tileHeight + p.sideLengthY;
            }

            startPos.rx() += p.columnWidth;
        }
    } else {
        // Odd row shifting is applied in the rendering loop, so un-apply it here
        if (p.doStaggerY(startTile.y()))
            startPos.rx() -= p.columnWidth;

        for (; startPos.y() <= rect.bottom() && startTile.y() < map()->height(); startTile.ry()++) {
            QPoint rowTile = startTile;
            QPoint rowPos = startPos;

            if (p.doStaggerY(startTile.y()))
                rowPos.rx() += p.columnWidth;

            for (; rowPos.x() <= rect.right() && rowTile.x() < map()->width(); rowTile.rx()++) {
                lines.append(QLine(rowPos + oct[0], rowPos + oct[1]));
                lines.append(QLine(rowPos + oct[1], rowPos + oct[2]));
                lines.append(QLine(rowPos + oct[3], rowPos + oct[4]));

                const bool isStaggered = p.doStaggerY(startTile.y());
                const bool lastRow = rowTile.y() == map()->height() - 1;
                const bool lastColumn = rowTile.x() == map()->width() - 1;
                const bool bottomLeft = lastRow || (rowTile.x() == 0 && !isStaggered);
                const bool bottomRight = lastRow || (lastColumn && isStaggered);

                if (lastColumn)
                    lines.append(QLine(rowPos + oct[4], rowPos + oct[5]));
                if (bottomRight)
                    lines.append(QLine(rowPos + oct[5], rowPos + oct[6]));
                if (bottomLeft)
                    lines.append(QLine(rowPos + oct[7], rowPos + oct[0]));

                painter->drawLines(lines);
                lines.resize(0);

                rowPos.rx() += p.tileWidth + p.sideLengthX;
            }

            startPos.ry() += p.rowHeight;
        }
    }
}
/*!
  Draw dots

  \param painter Painter
  \param xMap x map
  \param yMap y map
  \param canvasRect Contents rectangle of the canvas
  \param from index of the first point to be painted
  \param to index of the last point to be painted

  \sa draw(), drawCurve(), drawSticks(), drawLines(), drawSteps()
*/
void QwtPlotCurve::drawDots( QPainter *painter,
    const QwtScaleMap &xMap, const QwtScaleMap &yMap,
    const QRectF &canvasRect, int from, int to ) const
{
    const QColor color = painter->pen().color();

    if ( painter->pen().style() == Qt::NoPen || color.alpha() == 0 )
    {
        return;
    }

    const bool doFill = ( d_data->brush.style() != Qt::NoBrush )
            && ( d_data->brush.color().alpha() > 0 );
    const bool doAlign = QwtPainter::roundingAlignment( painter );

    QwtPointMapper mapper;
    mapper.setBoundingRect( canvasRect );
    mapper.setFlag( QwtPointMapper::RoundPoints, doAlign );

    if ( d_data->paintAttributes & FilterPoints )
    {
        if ( ( color.alpha() == 255 )
            && !( painter->renderHints() & QPainter::Antialiasing ) )
        {
            mapper.setFlag( QwtPointMapper::WeedOutPoints, true );
        }
    }

    if ( doFill )
    {
        mapper.setFlag( QwtPointMapper::WeedOutPoints, false );

        QPolygonF points = mapper.toPointsF( 
            xMap, yMap, data(), from, to );

        QwtPainter::drawPoints( painter, points );
        fillCurve( painter, xMap, yMap, canvasRect, points );
    }
    else if ( d_data->paintAttributes & ImageBuffer )
    {
        const QImage image = mapper.toImage( xMap, yMap,
            data(), from, to, d_data->pen, 
            painter->testRenderHint( QPainter::Antialiasing ),
            renderThreadCount() );

        painter->drawImage( canvasRect.toAlignedRect(), image );
    }
    else if ( d_data->paintAttributes & MinimizeMemory )
    {
        const QwtSeriesData<QPointF> *series = data();

        for ( int i = from; i <= to; i++ )
        {
            const QPointF sample = series->sample( i );

            double xi = xMap.transform( sample.x() );
            double yi = yMap.transform( sample.y() );

            if ( doAlign )
            {
                xi = qRound( xi );
                yi = qRound( yi );
            }

            QwtPainter::drawPoint( painter, QPointF( xi, yi ) );
        }
    }
    else
    {
        if ( doAlign )
        {
            const QPolygon points = mapper.toPoints(
                xMap, yMap, data(), from, to ); 

            QwtPainter::drawPoints( painter, points );
        }
        else
        {
            const QPolygonF points = mapper.toPointsF( 
                xMap, yMap, data(), from, to );

            QwtPainter::drawPoints( painter, points );
        }
    }
}
Exemple #10
0
void KisOpenGLCanvas2::drawImage()
{
    if (!d->displayShader) {
        return;
    }

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

    KisCoordinatesConverter *converter = coordinatesConverter();

    d->displayShader->bind();

    QMatrix4x4 projectionMatrix;
    projectionMatrix.setToIdentity();
    projectionMatrix.ortho(0, width(), height(), 0, NEAR_VAL, FAR_VAL);

    // Set view/projection matrices
    QMatrix4x4 modelMatrix(coordinatesConverter()->imageToWidgetTransform());
    modelMatrix.optimize();
    modelMatrix = projectionMatrix * modelMatrix;
    d->displayShader->setUniformValue(d->displayShader->location(Uniform::ModelViewProjection), modelMatrix);

    QMatrix4x4 textureMatrix;
    textureMatrix.setToIdentity();
    d->displayShader->setUniformValue(d->displayShader->location(Uniform::TextureMatrix), textureMatrix);

    QRectF widgetRect(0,0, width(), height());
    QRectF widgetRectInImagePixels = converter->documentToImage(converter->widgetToDocument(widgetRect));

    qreal scaleX, scaleY;
    converter->imageScale(&scaleX, &scaleY);
    d->displayShader->setUniformValue(d->displayShader->location(Uniform::ViewportScale), (GLfloat) scaleX);
    d->displayShader->setUniformValue(d->displayShader->location(Uniform::TexelSize), (GLfloat) d->openGLImageTextures->texelSize());

    QRect ir = d->openGLImageTextures->storedImageBounds();
    QRect wr = widgetRectInImagePixels.toAlignedRect();

    if (!d->wrapAroundMode) {
        // if we don't want to paint wrapping images, just limit the
        // processing area, and the code will handle all the rest
        wr &= ir;
    }

    int firstColumn = d->xToColWithWrapCompensation(wr.left(), ir);
    int lastColumn = d->xToColWithWrapCompensation(wr.right(), ir);
    int firstRow = d->yToRowWithWrapCompensation(wr.top(), ir);
    int lastRow = d->yToRowWithWrapCompensation(wr.bottom(), ir);

    int minColumn = d->openGLImageTextures->xToCol(ir.left());
    int maxColumn = d->openGLImageTextures->xToCol(ir.right());
    int minRow = d->openGLImageTextures->yToRow(ir.top());
    int maxRow = d->openGLImageTextures->yToRow(ir.bottom());

    int imageColumns = maxColumn - minColumn + 1;
    int imageRows = maxRow - minRow + 1;

    for (int col = firstColumn; col <= lastColumn; col++) {
        for (int row = firstRow; row <= lastRow; row++) {

            int effectiveCol = col;
            int effectiveRow = row;
            QPointF tileWrappingTranslation;

            if (effectiveCol > maxColumn || effectiveCol < minColumn) {
                int translationStep = floor(qreal(col) / imageColumns);
                int originCol = translationStep * imageColumns;
                effectiveCol = col - originCol;
                tileWrappingTranslation.rx() = translationStep * ir.width();
            }

            if (effectiveRow > maxRow || effectiveRow < minRow) {
                int translationStep = floor(qreal(row) / imageRows);
                int originRow = translationStep * imageRows;
                effectiveRow = row - originRow;
                tileWrappingTranslation.ry() = translationStep * ir.height();
            }

            KisTextureTile *tile =
                    d->openGLImageTextures->getTextureTileCR(effectiveCol, effectiveRow);

            if (!tile) {
                warnUI << "OpenGL: Trying to paint texture tile but it has not been created yet.";
                continue;
            }

            /*
             * We create a float rect here to workaround Qt's
             * "history reasons" in calculation of right()
             * and bottom() coordinates of integer rects.
             */
            QRectF textureRect(tile->tileRectInTexturePixels());
            QRectF modelRect(tile->tileRectInImagePixels().translated(tileWrappingTranslation.x(), tileWrappingTranslation.y()));

            //Setup the geometry for rendering
            if (KisOpenGL::hasOpenGL3()) {
                rectToVertices(d->vertices, modelRect);

                d->quadBuffers[0].bind();
                d->quadBuffers[0].write(0, d->vertices, 3 * 6 * sizeof(float));

                rectToTexCoords(d->texCoords, textureRect);
                d->quadBuffers[1].bind();
                d->quadBuffers[1].write(0, d->texCoords, 2 * 6 * sizeof(float));
            }
            else {
                rectToVertices(d->vertices, modelRect);
                d->displayShader->enableAttributeArray(PROGRAM_VERTEX_ATTRIBUTE);
                d->displayShader->setAttributeArray(PROGRAM_VERTEX_ATTRIBUTE, d->vertices);

                rectToTexCoords(d->texCoords, textureRect);
                d->displayShader->enableAttributeArray(PROGRAM_TEXCOORD_ATTRIBUTE);
                d->displayShader->setAttributeArray(PROGRAM_TEXCOORD_ATTRIBUTE, d->texCoords);
            }

            if (d->displayFilter) {
                glActiveTexture(GL_TEXTURE0 + 1);
                glBindTexture(GL_TEXTURE_3D, d->displayFilter->lutTexture());
                d->displayShader->setUniformValue(d->displayShader->location(Uniform::Texture1), 1);
            }

            int currentLodPlane = tile->currentLodPlane();
            if (d->displayShader->location(Uniform::FixedLodLevel) >= 0) {
                d->displayShader->setUniformValue(d->displayShader->location(Uniform::FixedLodLevel),
                                                  (GLfloat) currentLodPlane);
            }

            glActiveTexture(GL_TEXTURE0);
            tile->bindToActiveTexture();

            if (currentLodPlane > 0) {
                glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST);
            } else if (SCALE_MORE_OR_EQUAL_TO(scaleX, scaleY, 2.0)) {
                glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
                glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
            } else {
                glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);

                switch(d->filterMode) {
                case KisOpenGL::NearestFilterMode:
                    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
                    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
                    break;
                case KisOpenGL::BilinearFilterMode:
                    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
                    break;
                case KisOpenGL::TrilinearFilterMode:
                    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
                    break;
                case KisOpenGL::HighQualityFiltering:
                    if (SCALE_LESS_THAN(scaleX, scaleY, 0.5)) {
                        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST);
                    } else {
                        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
                    }
                    break;
                }
            }

            glDrawArrays(GL_TRIANGLES, 0, 6);
        }
    }

    glBindTexture(GL_TEXTURE_2D, 0);
    d->displayShader->release();
    glBindBuffer(GL_ARRAY_BUFFER, 0);
}
void IsometricRenderer::drawTileLayer(QPainter *painter,
                                      const TileLayer *layer,
                                      const QRectF &exposed) const
{
    const int tileWidth = map()->tileWidth();
    const int tileHeight = map()->tileHeight();

    if (tileWidth <= 0 || tileHeight <= 1)
        return;

    QRect rect = exposed.toAlignedRect();
    if (rect.isNull())
        rect = boundingRect(layer->bounds());

    QMargins drawMargins = layer->drawMargins();
    drawMargins.setTop(drawMargins.top() - tileHeight);
    drawMargins.setRight(drawMargins.right() - tileWidth);

    rect.adjust(-drawMargins.right(),
                -drawMargins.bottom(),
                drawMargins.left(),
                drawMargins.top());

    // Determine the tile and pixel coordinates to start at
    QPointF tilePos = pixelToTileCoords(rect.x(), rect.y());
    QPoint rowItr = QPoint((int) std::floor(tilePos.x()),
                           (int) std::floor(tilePos.y()));
    QPointF startPos = tileToPixelCoords(rowItr);
    startPos.rx() -= tileWidth / 2;
    startPos.ry() += tileHeight;

    // Compensate for the layer position
    rowItr -= QPoint(layer->x(), layer->y());

    /* Determine in which half of the tile the top-left corner of the area we
     * need to draw is. If we're in the upper half, we need to start one row
     * up due to those tiles being visible as well. How we go up one row
     * depends on whether we're in the left or right half of the tile.
     */
    const bool inUpperHalf = startPos.y() - rect.y() > tileHeight / 2;
    const bool inLeftHalf = rect.x() - startPos.x() < tileWidth / 2;

    if (inUpperHalf) {
        if (inLeftHalf) {
            --rowItr.rx();
            startPos.rx() -= tileWidth / 2;
        } else {
            --rowItr.ry();
            startPos.rx() += tileWidth / 2;
        }
        startPos.ry() -= tileHeight / 2;
    }

    // Determine whether the current row is shifted half a tile to the right
    bool shifted = inUpperHalf ^ inLeftHalf;

    QTransform baseTransform = painter->transform();

    for (int y = startPos.y(); y - tileHeight < rect.bottom();
         y += tileHeight / 2)
    {
        QPoint columnItr = rowItr;

        for (int x = startPos.x(); x < rect.right(); x += tileWidth) {
            if (layer->contains(columnItr)) {
                const Cell &cell = layer->cellAt(columnItr);
                if (!cell.isEmpty()) {
                    const QPixmap &img = cell.tile->image();
                    const QPoint offset = cell.tile->tileset()->tileOffset();

                    qreal m11 = 1;      // Horizontal scaling factor
                    qreal m12 = 0;      // Vertical shearing factor
                    qreal m21 = 0;      // Horizontal shearing factor
                    qreal m22 = 1;      // Vertical scaling factor
                    qreal dx = offset.x() + x;
                    qreal dy = offset.y() + y - img.height();

                    if (cell.flippedAntiDiagonally) {
                        // Use shearing to swap the X/Y axis
                        m11 = 0;
                        m12 = 1;
                        m21 = 1;
                        m22 = 0;

                        // Compensate for the swap of image dimensions
                        dy += img.height() - img.width();
                    }
                    if (cell.flippedHorizontally) {
                        m11 = -m11;
                        m21 = -m21;
                        dx += cell.flippedAntiDiagonally ? img.height()
                                                         : img.width();
                    }
                    if (cell.flippedVertically) {
                        m12 = -m12;
                        m22 = -m22;
                        dy += cell.flippedAntiDiagonally ? img.width()
                                                         : img.height();
                    }

                    const QTransform transform(m11, m12, m21, m22, dx, dy);
                    painter->setTransform(transform * baseTransform);

                    painter->drawPixmap(0, 0, img);
                }
            }

            // Advance to the next column
            ++columnItr.rx();
            --columnItr.ry();
        }

        // Advance to the next row
        if (!shifted) {
            ++rowItr.rx();
            startPos.rx() += tileWidth / 2;
            shifted = true;
        } else {
            ++rowItr.ry();
            startPos.rx() -= tileWidth / 2;
            shifted = false;
        }
    }

    painter->setTransform(baseTransform);
}
/*!
  \brief Draw lines

  If the CurveAttribute Fitted is enabled a QwtCurveFitter tries
  to interpolate/smooth the curve, before it is painted.

  \param painter Painter
  \param xMap x map
  \param yMap y map
  \param canvasRect Contents rectangle of the canvas
  \param from index of the first point to be painted
  \param to index of the last point to be painted

  \sa setCurveAttribute(), setCurveFitter(), draw(),
      drawLines(), drawDots(), drawSteps(), drawSticks()
*/
void QwtPlotCurve::drawLines( QPainter *painter,
    const QwtScaleMap &xMap, const QwtScaleMap &yMap,
    const QRectF &canvasRect, int from, int to ) const
{
    if ( from > to )
        return;

    const bool doAlign = QwtPainter::roundingAlignment( painter );
    const bool doFit = ( d_data->attributes & Fitted ) && d_data->curveFitter;
    const bool doFill = ( d_data->brush.style() != Qt::NoBrush )
            && ( d_data->brush.color().alpha() > 0 );

    QRectF clipRect;
    if ( d_data->paintAttributes & ClipPolygons )
    {
        clipRect = qwtIntersectedClipRect( canvasRect, painter );

        const qreal pw = qMax( qreal( 1.0 ), painter->pen().widthF());
        clipRect = clipRect.adjusted(-pw, -pw, pw, pw);
    }

    bool doIntegers = false;

#if QT_VERSION < 0x040800
    if ( painter->paintEngine()->type() == QPaintEngine::Raster )
    {

        // For Qt <= 4.7 the raster paint engine is significantly faster
        // for rendering QPolygon than for QPolygonF. So let's
        // see if we can use it.

        // In case of filling or fitting performance doesn't count
        // because both operations are much more expensive
        // then drawing the polyline itself

        if ( !doFit && !doFill )
            doIntegers = true; 
    }
#endif

    QwtPointMapper mapper;

    if ( doAlign )
    {
        mapper.setFlag( QwtPointMapper::RoundPoints, true );
        mapper.setFlag( QwtPointMapper::WeedOutIntermediatePoints, 
            testPaintAttribute( FilterPointsAggressive ) );
    }

    mapper.setFlag( QwtPointMapper::WeedOutPoints, 
        testPaintAttribute( FilterPoints ) || 
        testPaintAttribute( FilterPointsAggressive ) );

    mapper.setBoundingRect( canvasRect );

    if ( doIntegers )
    {
        QPolygon polyline = mapper.toPolygon( 
            xMap, yMap, data(), from, to );

        if ( testPaintAttribute( ClipPolygons ) )
        {
            polyline = QwtClipper::clipPolygon( 
                clipRect.toAlignedRect(), polyline, false );
        }

        QwtPainter::drawPolyline( painter, polyline );
    }
    else
    {
        QPolygonF polyline = mapper.toPolygonF( xMap, yMap, data(), from, to );

        if ( doFill )
        {
            if ( doFit )
            {
                // it might be better to extend and draw the curvePath, but for 
                // the moment we keep an implementation, where we translate the
                // path back to a polyline.

                polyline = d_data->curveFitter->fitCurve( polyline );
            }

            if ( painter->pen().style() != Qt::NoPen )
            {
                // here we are wasting memory for the filled copy,
                // do polygon clipping twice etc .. TODO

                QPolygonF filled = polyline;
                fillCurve( painter, xMap, yMap, canvasRect, filled );
                filled.clear();

                if ( d_data->paintAttributes & ClipPolygons )
                    polyline = QwtClipper::clipPolygonF( clipRect, polyline, false );

                QwtPainter::drawPolyline( painter, polyline );
            }
            else
            {
                fillCurve( painter, xMap, yMap, canvasRect, polyline );
            }
        }
        else
        {
            if ( testPaintAttribute( ClipPolygons ) )
            {
                polyline = QwtClipper::clipPolygonF( 
                    clipRect, polyline, false );
            }

            if ( doFit )
            {
                if ( d_data->curveFitter->mode() == QwtCurveFitter::Path )
                {
                    const QPainterPath curvePath = 
                        d_data->curveFitter->fitCurvePath( polyline );

                    painter->drawPath( curvePath );
                }
                else
                {
                    polyline = d_data->curveFitter->fitCurve( polyline );
                    QwtPainter::drawPolyline( painter, polyline );
                }
            }
            else
            {
                QwtPainter::drawPolyline( painter, polyline );
            }
        }
    }
}
Exemple #13
0
void HexagonalRenderer::drawTileLayer(QPainter *painter,
                                      const TileLayer *layer,
                                      const QRectF &exposed) const
{
    const RenderParams p(map());

    QRect rect = exposed.toAlignedRect();

    if (rect.isNull())
        rect = boundingRect(layer->bounds());

    QMargins drawMargins = layer->drawMargins();
    drawMargins.setBottom(drawMargins.bottom() + p.tileHeight);
    drawMargins.setRight(drawMargins.right() - p.tileWidth);

    rect.adjust(-drawMargins.right(),
                -drawMargins.bottom(),
                drawMargins.left(),
                drawMargins.top());

    // Determine the tile and pixel coordinates to start at
    QPoint startTile = screenToTileCoords(rect.topLeft()).toPoint();

    // Compensate for the layer position
    startTile -= layer->position();

    QPoint startPos = tileToScreenCoords(startTile + layer->position()).toPoint();

    /* Determine in which half of the tile the top-left corner of the area we
     * need to draw is. If we're in the upper half, we need to start one row
     * up due to those tiles being visible as well. How we go up one row
     * depends on whether we're in the left or right half of the tile.
     */
    const bool inUpperHalf = rect.y() - startPos.y() < p.sideOffsetY;
    const bool inLeftHalf = rect.x() - startPos.x() < p.sideOffsetX;

    if (inUpperHalf)
        startTile.ry()--;
    if (inLeftHalf)
        startTile.rx()--;

    CellRenderer renderer(painter, CellRenderer::HexagonalCells);

    if (p.staggerX) {
        startTile.setX(qMax(-1, startTile.x()));
        startTile.setY(qMax(-1, startTile.y()));

        startPos = tileToScreenCoords(startTile + layer->position()).toPoint();
        startPos.ry() += p.tileHeight;

        bool staggeredRow = p.doStaggerX(startTile.x() + layer->x());

        for (; startPos.y() < rect.bottom() && startTile.y() < layer->height();) {
            QPoint rowTile = startTile;
            QPoint rowPos = startPos;

            for (; rowPos.x() < rect.right() && rowTile.x() < layer->width(); rowTile.rx() += 2) {
                if (layer->contains(rowTile)) {
                    const Cell &cell = layer->cellAt(rowTile);

                    if (!cell.isEmpty()) {
                        Tile *tile = cell.tile();
                        QSize size = tile ? tile->size() : map()->tileSize();
                        renderer.render(cell, rowPos, size, CellRenderer::BottomLeft);
                    }
                }

                rowPos.rx() += p.tileWidth + p.sideLengthX;
            }

            if (staggeredRow) {
                startTile.rx() -= 1;
                startTile.ry() += 1;
                startPos.rx() -= p.columnWidth;
                staggeredRow = false;
            } else {
                startTile.rx() += 1;
                startPos.rx() += p.columnWidth;
                staggeredRow = true;
            }

            startPos.ry() += p.rowHeight;
        }
    } else {
        startTile.setX(qMax(0, startTile.x()));
        startTile.setY(qMax(0, startTile.y()));

        startPos = tileToScreenCoords(startTile + layer->position()).toPoint();
        startPos.ry() += p.tileHeight;

        // Odd row shifting is applied in the rendering loop, so un-apply it here
        if (p.doStaggerY(startTile.y() + layer->y()))
            startPos.rx() -= p.columnWidth;

        for (; startPos.y() < rect.bottom() && startTile.y() < layer->height(); startTile.ry()++) {
            QPoint rowTile = startTile;
            QPoint rowPos = startPos;

            if (p.doStaggerY(startTile.y() + layer->y()))
                rowPos.rx() += p.columnWidth;

            for (; rowPos.x() < rect.right() && rowTile.x() < layer->width(); rowTile.rx()++) {
                const Cell &cell = layer->cellAt(rowTile);

                if (!cell.isEmpty()) {
                    Tile *tile = cell.tile();
                    QSize size = tile ? tile->size() : map()->tileSize();
                    renderer.render(cell, rowPos, size, CellRenderer::BottomLeft);
                }

                rowPos.rx() += p.tileWidth + p.sideLengthX;
            }

            startPos.ry() += p.rowHeight;
        }
    }
}
void IsometricRenderer::drawTileLayer(QPainter *painter,
                                      const TileLayer *layer,
                                      const QRectF &exposed) const
{
    const int tileWidth = map()->tileWidth();
    const int tileHeight = map()->tileHeight();

    if (tileWidth <= 0 || tileHeight <= 1)
        return;

    QRect rect = exposed.toAlignedRect();
    if (rect.isNull())
        rect = boundingRect(layer->bounds());

    QMargins drawMargins = layer->drawMargins();
    drawMargins.setTop(drawMargins.top() - tileHeight);
    drawMargins.setRight(drawMargins.right() - tileWidth);

    rect.adjust(-drawMargins.right(),
                -drawMargins.bottom(),
                drawMargins.left(),
                drawMargins.top());

    // Determine the tile and pixel coordinates to start at
    QPointF tilePos = screenToTileCoords(rect.x(), rect.y());
    QPoint rowItr = QPoint((int) std::floor(tilePos.x()),
                           (int) std::floor(tilePos.y()));
    QPointF startPos = tileToScreenCoords(rowItr);
    startPos.rx() -= tileWidth / 2;
    startPos.ry() += tileHeight;

    // Compensate for the layer position
    rowItr -= QPoint(layer->x(), layer->y());

    /* Determine in which half of the tile the top-left corner of the area we
     * need to draw is. If we're in the upper half, we need to start one row
     * up due to those tiles being visible as well. How we go up one row
     * depends on whether we're in the left or right half of the tile.
     */
    const bool inUpperHalf = startPos.y() - rect.y() > tileHeight / 2;
    const bool inLeftHalf = rect.x() - startPos.x() < tileWidth / 2;

    if (inUpperHalf) {
        if (inLeftHalf) {
            --rowItr.rx();
            startPos.rx() -= tileWidth / 2;
        } else {
            --rowItr.ry();
            startPos.rx() += tileWidth / 2;
        }
        startPos.ry() -= tileHeight / 2;
    }

    // Determine whether the current row is shifted half a tile to the right
    bool shifted = inUpperHalf ^ inLeftHalf;

    CellRenderer renderer(painter);

    for (int y = startPos.y(); y - tileHeight < rect.bottom();
         y += tileHeight / 2)
    {
        QPoint columnItr = rowItr;

        for (int x = startPos.x(); x < rect.right(); x += tileWidth) {
            if (layer->contains(columnItr)) {
                const Cell &cell = layer->cellAt(columnItr);
                if (!cell.isEmpty()) {
                    renderer.render(cell, QPointF(x, y), QSizeF(0, 0),
                                    CellRenderer::BottomLeft);
                }
            }

            // Advance to the next column
            ++columnItr.rx();
            --columnItr.ry();
        }

        // Advance to the next row
        if (!shifted) {
            ++rowItr.rx();
            startPos.rx() += tileWidth / 2;
            shifted = true;
        } else {
            ++rowItr.ry();
            startPos.rx() -= tileWidth / 2;
            shifted = false;
        }
    }
}
Exemple #15
0
void ImageView::draw(QPainter& p, const QRectF& R, const QImage& image) {
    QRect aR = R.toAlignedRect();
    p.drawImage(aR.x(), aR.y(), image.copy(aR));
}
/*!
  \brief Draw lines

  If the CurveAttribute Fitted is enabled a QwtCurveFitter tries
  to interpolate/smooth the curve, before it is painted.

  \param painter Painter
  \param xMap x map
  \param yMap y map
  \param canvasRect Contents rectangle of the canvas
  \param from index of the first point to be painted
  \param to index of the last point to be painted

  \sa setCurveAttribute(), setCurveFitter(), draw(),
      drawLines(), drawDots(), drawSteps(), drawSticks()
*/
void QwtPlotCurve::drawLines( QPainter *painter,
    const QwtScaleMap &xMap, const QwtScaleMap &yMap,
    const QRectF &canvasRect, int from, int to ) const
{
    if ( from > to )
        return;

    const bool doAlign = QwtPainter::roundingAlignment( painter );
    const bool doFit = ( d_data->attributes & Fitted ) && d_data->curveFitter;
    const bool doFill = ( d_data->brush.style() != Qt::NoBrush )
            && ( d_data->brush.color().alpha() > 0 );

    QRectF clipRect;
    if ( d_data->paintAttributes & ClipPolygons )
    {
        qreal pw = qMax( qreal( 1.0 ), painter->pen().widthF());
        clipRect = canvasRect.adjusted(-pw, -pw, pw, pw);
    }

    bool doIntegers = false;

#if QT_VERSION < 0x040800

    // For Qt <= 4.7 the raster paint engine is significantly faster
    // for rendering QPolygon than for QPolygonF. So let's
    // see if we can use it.

    if ( painter->paintEngine()->type() == QPaintEngine::Raster )
    {
        // In case of filling or fitting performance doesn't count
        // because both operations are much more expensive
        // then drawing the polyline itself

        if ( !doFit && !doFill )
            doIntegers = true; 
    }
#endif

    const bool noDuplicates = d_data->paintAttributes & FilterPoints;

    QwtPointMapper mapper;
    mapper.setFlag( QwtPointMapper::RoundPoints, doAlign );
    mapper.setFlag( QwtPointMapper::WeedOutPoints, noDuplicates );
    mapper.setBoundingRect( canvasRect );

    if ( doIntegers )
    {
        QPolygon polyline = mapper.toPolygon( 
            xMap, yMap, data(), from, to );

        if ( d_data->paintAttributes & ClipPolygons )
        {
            polyline = QwtClipper::clipPolygon( 
                clipRect.toAlignedRect(), polyline, false );
        }

        QwtPainter::drawPolyline( painter, polyline );
    }
    else
    {
        QPolygonF polyline = mapper.toPolygonF( xMap, yMap, data(), from, to );

        if ( doFit )
            polyline = d_data->curveFitter->fitCurve( polyline );

        if ( doFill )
        {
            if ( painter->pen().style() != Qt::NoPen )
            {
                // here we are wasting memory for the filled copy,
                // do polygon clipping twice etc .. TODO

                QPolygonF filled = polyline;
                fillCurve( painter, xMap, yMap, canvasRect, filled );
                filled.clear();

                if ( d_data->paintAttributes & ClipPolygons )
                {
                    polyline = QwtClipper::clipPolygonF( 
                        clipRect, polyline, false );
                }

                QwtPainter::drawPolyline( painter, polyline );
            }
            else
            {
                fillCurve( painter, xMap, yMap, canvasRect, polyline );
            }
        }
        else
        {
            if ( d_data->paintAttributes & ClipPolygons )
            {
                polyline = QwtClipper::clipPolygonF(
                    clipRect, polyline, false );
            }

            QwtPainter::drawPolyline( painter, polyline );
        }
    }
}
void QAlphaPaintEnginePrivate::addAlphaRect(const QRectF &rect)
{
    m_alphargn |= rect.toAlignedRect();
}
Exemple #18
0
/*!
  Draw a color bar into a rectangle

  \param painter Painter
  \param colorMap Color map
  \param interval Value range
  \param scaleMap Scale map
  \param orientation Orientation
  \param rect Traget rectangle
*/
void QwtPainter::drawColorBar( QPainter *painter,
        const QwtColorMap &colorMap, const QwtInterval &interval,
        const QwtScaleMap &scaleMap, Qt::Orientation orientation,
        const QRectF &rect )
{
    QVector<QRgb> colorTable;
    if ( colorMap.format() == QwtColorMap::Indexed )
        colorTable = colorMap.colorTable( interval );

    QColor c;

    const QRect devRect = rect.toAlignedRect();

    /*
      We paint to a pixmap first to have something scalable for printing
      ( f.e. in a Pdf document )
     */

    QPixmap pixmap( devRect.size() );
    QPainter pmPainter( &pixmap );
    pmPainter.translate( -devRect.x(), -devRect.y() );

    if ( orientation == Qt::Horizontal )
    {
        QwtScaleMap sMap = scaleMap;
        sMap.setPaintInterval( rect.left(), rect.right() );

        for ( int x = devRect.left(); x <= devRect.right(); x++ )
        {
            const double value = sMap.invTransform( x );

            if ( colorMap.format() == QwtColorMap::RGB )
                c.setRgb( colorMap.rgb( interval, value ) );
            else
                c = colorTable[colorMap.colorIndex( interval, value )];

            pmPainter.setPen( c );
            pmPainter.drawLine( x, devRect.top(), x, devRect.bottom() );
        }
    }
    else // Vertical
    {
        QwtScaleMap sMap = scaleMap;
        sMap.setPaintInterval( rect.bottom(), rect.top() );

        for ( int y = devRect.top(); y <= devRect.bottom(); y++ )
        {
            const double value = sMap.invTransform( y );

            if ( colorMap.format() == QwtColorMap::RGB )
                c.setRgb( colorMap.rgb( interval, value ) );
            else
                c = colorTable[colorMap.colorIndex( interval, value )];

            pmPainter.setPen( c );
            pmPainter.drawLine( devRect.left(), y, devRect.right(), y );
        }
    }
    pmPainter.end();

    drawPixmap( painter, rect, pixmap );
}
void StaggeredRenderer::drawTileLayer(QPainter *painter,
                                      const TileLayer *layer,
                                      const QRectF &exposed) const
{
    const int tileWidth = map()->tileWidth();
    const int tileHeight = map()->tileHeight();

    QRect rect = exposed.toAlignedRect();
    if (rect.isNull())
        rect = boundingRect(layer->bounds());

    QMargins drawMargins = layer->drawMargins();
    drawMargins.setRight(drawMargins.right() - tileWidth);

    rect.adjust(-drawMargins.right(),
                -drawMargins.bottom(),
                drawMargins.left(),
                drawMargins.top());

    // Determine the tile and pixel coordinates to start at
    QPoint startTile = pixelToTileCoords(rect.x(), rect.y()).toPoint();

    // Compensate for the layer position
    startTile -= layer->position();

    QPoint startPos = tileToPixelCoords(startTile + layer->position()).toPoint();

    /* Determine in which half of the tile the top-left corner of the area we
     * need to draw is. If we're in the upper half, we need to start one row
     * up due to those tiles being visible as well. How we go up one row
     * depends on whether we're in the left or right half of the tile.
     */
    const bool inUpperHalf = startPos.y() - rect.y() > tileHeight / 2;
    const bool inLeftHalf = rect.x() - startPos.x() < tileWidth / 2;

    if (inUpperHalf)
        startTile.ry()--;
    if (inLeftHalf)
        startTile.rx()--;

    startTile.setX(qMax(0, startTile.x()));
    startTile.setY(qMax(0, startTile.y()));

    startPos = tileToPixelCoords(startTile + layer->position()).toPoint();
    startPos.ry() += tileHeight;

    // Odd row shifting is applied in the rendering loop, so un-apply it here
    if ((startTile.y() + layer->y()) % 2)
        startPos.rx() -= tileWidth / 2;

    CellRenderer renderer(painter);

    for (; startPos.y() < rect.bottom() && startTile.y() < layer->height(); startTile.ry()++) {
        QPoint rowTile = startTile;
        QPoint rowPos = startPos;

        if ((startTile.y() + layer->y()) % 2)
            rowPos.rx() += tileWidth / 2;

        for (; rowPos.x() < rect.right() && rowTile.x() < layer->width(); rowTile.rx()++) {
            const Cell &cell = layer->cellAt(rowTile);
            if (!cell.isEmpty())
                renderer.render(cell, rowPos, CellRenderer::BottomLeft);

            rowPos.rx() += tileWidth;
        }

        startPos.ry() += tileHeight / 2;
    }
}