Esempio n. 1
0
void PageItem::setRenderParam(const RenderParam& renderParam)
{
    if(m_renderParam != renderParam)
    {
        const bool resolutionChanged = m_renderParam.resolutionX() != renderParam.resolutionX()
                || m_renderParam.resolutionY() != renderParam.resolutionY()
                || !qFuzzyCompare(m_renderParam.devicePixelRatio(), renderParam.devicePixelRatio())
                || !qFuzzyCompare(m_renderParam.scaleFactor(), renderParam.scaleFactor());

        const bool rotationChanged = m_renderParam.rotation() != renderParam.rotation();

        const RenderFlags changedFlags = m_renderParam.flags() ^ renderParam.flags();

        refresh(!rotationChanged && changedFlags == 0);

        m_renderParam = renderParam;

        if(resolutionChanged || rotationChanged)
        {
            prepareGeometryChange();
            prepareGeometry();
        }

        if(changedFlags.testFlag(TrimMargins))
        {
            setFlag(QGraphicsItem::ItemClipsToShape, m_renderParam.trimMargins());
        }
    }
}
Esempio n. 2
0
void MiniMapRenderer::renderToImage(QImage& image, RenderFlags renderFlags) const
{
    if (!mMap)
        return;
    if (image.isNull())
        return;

    bool drawObjects = renderFlags.testFlag(RenderFlag::DrawMapObjects);
    bool drawTileLayers = renderFlags.testFlag(RenderFlag::DrawTileLayers);
    bool drawImageLayers = renderFlags.testFlag(RenderFlag::DrawImageLayers);
    bool drawTileGrid = renderFlags.testFlag(RenderFlag::DrawGrid);
    bool visibleLayersOnly = renderFlags.testFlag(RenderFlag::IgnoreInvisibleLayer);

    QRect mapBoundingRect = mRenderer->mapBoundingRect();

    if (renderFlags.testFlag(IncludeOverhangingTiles))
        extendMapRect(mapBoundingRect, *mRenderer);

    QSize mapSize = mapBoundingRect.size();
    QMargins margins = mMap->computeLayerOffsetMargins();
    mapSize.setWidth(mapSize.width() + margins.left() + margins.right());
    mapSize.setHeight(mapSize.height() + margins.top() + margins.bottom());

    // Determine the largest possible scale
    qreal scale = qMin(static_cast<qreal>(image.width()) / mapSize.width(),
                       static_cast<qreal>(image.height()) / mapSize.height());

    if (renderFlags.testFlag(DrawBackground)) {
        if (mMap->backgroundColor().isValid())
            image.fill(mMap->backgroundColor());
        else
            image.fill(Qt::gray);
    } else {
        image.fill(Qt::transparent);
    }

    QPainter painter(&image);
    painter.setRenderHints(QPainter::SmoothPixmapTransform, renderFlags.testFlag(SmoothPixmapTransform));

    // Center the map in the requested size
    QSize scaledMapSize = mapSize * scale;
    QPointF centerOffset((image.width() - scaledMapSize.width()) / 2,
                         (image.height() - scaledMapSize.height()) / 2);

    painter.translate(centerOffset);
    painter.scale(scale, scale);
    painter.translate(margins.left(), margins.top());
    painter.translate(-mapBoundingRect.topLeft());

    mRenderer->setPainterScale(scale);

    LayerIterator iterator(mMap);
    while (const Layer *layer = iterator.next()) {
        if (visibleLayersOnly && layer->isHidden())
            continue;

        const auto offset = layer->totalOffset();

        painter.setOpacity(layer->effectiveOpacity());
        painter.translate(offset);

        switch (layer->layerType()) {
        case Layer::TileLayerType: {
            if (drawTileLayers) {
                const TileLayer *tileLayer = static_cast<const TileLayer*>(layer);
                mRenderer->drawTileLayer(&painter, tileLayer);
            }
            break;
        }

        case Layer::ObjectGroupType: {
            if (drawObjects) {
                const ObjectGroup *objectGroup = static_cast<const ObjectGroup*>(layer);
                QList<MapObject*> objects = objectGroup->objects();

                if (objectGroup->drawOrder() == ObjectGroup::TopDownOrder)
                    std::stable_sort(objects.begin(), objects.end(), objectLessThan);

                for (const MapObject *object : qAsConst(objects)) {
                    if (object->isVisible()) {
                        if (object->rotation() != qreal(0)) {
                            QPointF origin = mRenderer->pixelToScreenCoords(object->position());
                            painter.save();
                            painter.translate(origin);
                            painter.rotate(object->rotation());
                            painter.translate(-origin);
                        }

                        const QColor color = object->effectiveColor();
                        mRenderer->drawMapObject(&painter, object, color);

                        if (object->rotation() != qreal(0))
                            painter.restore();
                    }
                }
            }
            break;
        }
        case Layer::ImageLayerType: {
            if (drawImageLayers) {
                const ImageLayer *imageLayer = static_cast<const ImageLayer*>(layer);
                mRenderer->drawImageLayer(&painter, imageLayer);
            }
            break;
        }

        case Layer::GroupLayerType:
            // Recursion handled by LayerIterator
            break;
        }

        painter.translate(-offset);
    }

    if (drawTileGrid) {
        Preferences *prefs = Preferences::instance();
        mRenderer->drawGrid(&painter, mapBoundingRect, prefs->gridColor());
    }
}