/** * @param x x coordinate * @param y y coordinate * @param image the image to draw * @param blend use alpha blending */ void Layer::putImage(int x, int y, QImage image, bool blend) { Q_ASSERT(image.format() == QImage::Format_ARGB32); // Protocol uses unsigned coordinates, so we don't need to support // negative values here either. Q_ASSERT(x>=0 && y>=0); if(x<0 || y<0) return; // Check if the image is completely outside the layer if(x >= _width || y >= _height) return; const int x0 = Tile::roundDown(x); const int y0 = Tile::roundDown(y); if(x-x0 || y-y0 || image.width() % Tile::SIZE || image.height() % Tile::SIZE || blend) { image = padImageToTileBoundary(x, y, image, blend); } const int tx0 = x0 / Tile::SIZE; const int ty0 = y0 / Tile::SIZE; const int tx1 = qMin((x0 + image.width() - 1) / Tile::SIZE, _xtiles-1); const int ty1 = qMin((y0 + image.height() - 1) / Tile::SIZE, _ytiles-1); for(int ty=ty0;ty<=ty1;++ty) { int yoff = (ty-ty0) * Tile::SIZE; for(int tx=tx0;tx<=tx1;++tx) { int xoff = (tx-tx0) * Tile::SIZE; int i = ty*_xtiles + tx; Q_ASSERT(i>=0 && i < _xtiles*_ytiles); _tiles[i] = Tile(image, xoff, yoff); } } if(_owner && visible()) { _owner->markDirty(QRect(x, y, image.width(), image.height())); _owner->notifyAreaChanged(); } }
/** * @param x x coordinate * @param y y coordinate * @param image the image to draw * @param mode blending/compositing mode (see protocol::PutImage) */ void Layer::putImage(int x, int y, QImage image, BlendMode::Mode mode) { Q_ASSERT(image.format() == QImage::Format_ARGB32); // Protocol uses unsigned coordinates, so we don't need to support // negative values here either. Q_ASSERT(x>=0 && y>=0); if(x<0 || y<0) return; // Check if the image is completely outside the layer if(x >= _width || y >= _height) return; const int x0 = Tile::roundDown(x); const int y0 = Tile::roundDown(y); Layer imageLayer = padImageToTileBoundary(x, y, image, mode); // Replace this layer's tiles with the scratch tiles const int tx0 = x0 / Tile::SIZE; const int ty0 = y0 / Tile::SIZE; const int tx1 = qMin((x0 + imageLayer.width() - 1) / Tile::SIZE, _xtiles-1); const int ty1 = qMin((y0 + imageLayer.height() - 1) / Tile::SIZE, _ytiles-1); for(int ty=ty0; ty<=ty1; ++ty) { for(int tx=tx0; tx<=tx1; ++tx) { rtile(tx, ty) = imageLayer.tile(tx-tx0, ty-ty0); } } if(_owner && visible()) { _owner->markDirty(QRect(x, y, image.width(), image.height())); _owner->notifyAreaChanged(); } }