void TileView::render( ImageObject& img, const Rect& r ) { int startX = (int)( (r.left + pScrollX) / pTileWidth ); int startY = (int)floor( (double)((r.top + pScrollY) / pTileHeight) ); int stopX = (int)ceil( (double)((r.left + pScrollX + r.width) / pTileWidth) ) + 1; int stopY = (int)ceil( (double)((r.top + pScrollY + r.height) / pTileHeight) ) + 1; if ( startX < 0 ) startX = 0; if ( startY < 0 ) startY = 0; if ( stopY < 0 ) stopY = 0; if ( stopY < 0 ) stopY = 0; if ( startX >= (int)pNumX ) startX = pNumX; if ( startY >= (int)pNumY ) startY = pNumY; if ( stopX >= (int)pNumX ) stopX = pNumX; if ( stopY >= (int)pNumY ) stopY = pNumY; // cout << "startX: " << startX << " startY: " << startY << " stopX: " << stopX << " stopY: " << stopY << endl; int x = pScrollX + (startX * pTileWidth); int y = pScrollY + (startY * pTileHeight); // cout << "absX: " << absoluteXPos() << " absY: " << absoluteYPos() << endl; // cout << "x: " << x << " y: " << y << endl; for ( int iy = startY; iy < stopY; iy++ ) { for ( int ix = startX; ix < stopX; ix++ ) { for( int i = 0; i < tiles(ix, iy).numTiles(); i++ ){ if ( tiles(ix, iy).tileImage( i ) >= 0 ) { gui().screen().drawImage( *tileImages().get( tiles(ix, iy).tileImage( i ) ), Rect( x, y, pTileWidth, pTileHeight ) ); } } for( int i = 0; i < tiles(ix, iy).numObjects(); i++ ){ if ( tiles(ix, iy).objectImage( i ) >= 0 ) { gui().screen().drawImage( *objectImages().get( tiles(ix, iy).objectImage( i ) ), Rect( x, y, pTileWidth, pTileHeight ) ); } } x += pTileWidth; } x = pScrollX + (startX * pTileWidth); y += pTileHeight; } }
// Tile images in a width x height rectangle. // xOrigin and yOrigin represent the location of this rectangle relative to the canvas // minDraw represents the minimum number of pixels to scale an image down to // tileType determines whether it tiles horizontally or vertically first void Tiler::tileImages(size_t width, size_t height, size_t xOrigin, size_t yOrigin, size_t minDraw, bool tileType) { size_t x = xOrigin, y = yOrigin; std::vector<std::unique_ptr<DrawOperation>> drawBatch; size_t imageNum; // Tile Horizontally if(tileType == 0) { while(1) { imageNum = randNum(0, imageFilePaths.size()-1); Magick::Image image(popImagePath(imageNum)); image.resize(Magick::Geometry("x" + std::to_string(height))); const size_t imageWidth = image.columns(); // If the last image wont fit, tile images in the empty space if(((x-xOrigin) + imageWidth) > width) { tileImages(width-(x-xOrigin), height, x, y, minDraw, 1); break; } // Put this draw operation in the queue drawBatch.emplace_back(std::make_unique<DrawOperation>(std::move(image), x, y)); x += imageWidth; // If we run out of room to draw, center what we have then stop if(((x-xOrigin) + minDraw) > width) { for(auto &&drawOperation : drawBatch) { drawOperation->x += (width-(x-xOrigin))/2; } break; } } } // Tile Vertically else { while(1) { imageNum = randNum(0, imageFilePaths.size()-1); Magick::Image image(popImagePath(imageNum)); image.resize(Magick::Geometry(std::to_string(width))); const size_t imageHeight = image.rows(); // If the last image wont fit, tile images in the empty space if((y-yOrigin+imageHeight) > height) { tileImages(width, height-(y-yOrigin), x, y, minDraw, 0); break; } // Put this draw operation in the queue drawBatch.emplace_back(std::make_unique<DrawOperation>(std::move(image), x, y)); y += imageHeight; // If we run out of room to draw, center what we have then stop if((y-yOrigin + minDraw) > height) { for(auto &&drawOperation : drawBatch) { drawOperation->y += (height-(y-yOrigin))/2; } break; } } } drawQueue.insert(drawQueue.end(), std::make_move_iterator(drawBatch.begin()), std::make_move_iterator(drawBatch.end())); }