2014-06-05 15:12:49 +00:00
|
|
|
#include "CanvasPortion.h"
|
|
|
|
|
2014-06-10 13:13:16 +00:00
|
|
|
#include <cassert>
|
2015-11-18 21:22:09 +00:00
|
|
|
#include <stdlib.h>
|
|
|
|
#include <vector>
|
2014-06-10 13:13:16 +00:00
|
|
|
|
|
|
|
#include "CanvasPixel.h"
|
2014-06-12 15:45:59 +00:00
|
|
|
#include "CanvasPreview.h"
|
2014-08-21 07:58:11 +00:00
|
|
|
#include "PackStream.h"
|
|
|
|
#include "FileSystem.h"
|
2015-11-18 21:22:09 +00:00
|
|
|
#include "System.h"
|
2014-06-10 13:13:16 +00:00
|
|
|
|
2015-11-09 21:30:46 +00:00
|
|
|
#define CHECK_COORDINATES() \
|
|
|
|
assert(x >= 0); \
|
|
|
|
assert(x < width); \
|
|
|
|
assert(y >= 0); \
|
|
|
|
assert(y < height); \
|
2014-08-18 15:16:17 +00:00
|
|
|
assert(pixels != NULL)
|
2014-06-10 13:13:16 +00:00
|
|
|
|
2015-11-18 21:22:09 +00:00
|
|
|
// Keep track of created files to erase them at program exit
|
2015-12-10 23:36:50 +00:00
|
|
|
static vector<string> _files;
|
2015-11-18 21:22:09 +00:00
|
|
|
static void clean_all_files() {
|
|
|
|
for (auto &filepath : _files) {
|
|
|
|
FileSystem::removeFile(filepath);
|
|
|
|
}
|
|
|
|
}
|
2015-12-10 23:36:50 +00:00
|
|
|
static int _atexit = atexit(clean_all_files);
|
2015-11-18 21:22:09 +00:00
|
|
|
|
2015-11-09 21:30:46 +00:00
|
|
|
CanvasPortion::CanvasPortion(int index, CanvasPreview *preview) : index(index), preview(preview) {
|
2014-06-10 13:13:16 +00:00
|
|
|
width = 1;
|
|
|
|
height = 1;
|
2014-08-18 15:33:15 +00:00
|
|
|
xoffset = 0;
|
|
|
|
yoffset = 0;
|
2014-08-18 15:16:17 +00:00
|
|
|
pixels = NULL;
|
2014-06-10 13:13:16 +00:00
|
|
|
}
|
|
|
|
|
2015-11-09 21:30:46 +00:00
|
|
|
CanvasPortion::~CanvasPortion() {
|
|
|
|
if (pixels) {
|
2014-08-18 15:16:17 +00:00
|
|
|
delete[] pixels;
|
|
|
|
}
|
2014-06-10 13:13:16 +00:00
|
|
|
}
|
|
|
|
|
2015-11-09 21:30:46 +00:00
|
|
|
int CanvasPortion::getFragmentCount(int x, int y) const {
|
2014-06-10 13:13:16 +00:00
|
|
|
CHECK_COORDINATES();
|
|
|
|
|
|
|
|
return pixels[y * width + x].getFragmentCount();
|
|
|
|
}
|
|
|
|
|
2015-11-09 21:30:46 +00:00
|
|
|
const CanvasFragment *CanvasPortion::getFrontFragment(int x, int y) const {
|
2014-06-10 13:13:16 +00:00
|
|
|
CHECK_COORDINATES();
|
|
|
|
|
|
|
|
return pixels[y * width + x].getFrontFragment();
|
|
|
|
}
|
|
|
|
|
2015-11-09 21:30:46 +00:00
|
|
|
void CanvasPortion::clear() {
|
2014-06-10 13:13:16 +00:00
|
|
|
int n = width * height;
|
2015-11-09 21:30:46 +00:00
|
|
|
for (int i = 0; i < n; i++) {
|
2014-06-10 13:13:16 +00:00
|
|
|
pixels[i].reset();
|
|
|
|
}
|
2014-06-05 15:12:49 +00:00
|
|
|
}
|
|
|
|
|
2015-11-09 21:30:46 +00:00
|
|
|
void CanvasPortion::setSize(int width, int height, int xoffset, int yoffset) {
|
2014-06-05 15:12:49 +00:00
|
|
|
this->width = width;
|
|
|
|
this->height = height;
|
2014-08-18 15:33:15 +00:00
|
|
|
this->xoffset = xoffset;
|
|
|
|
this->yoffset = yoffset;
|
2014-08-18 15:16:17 +00:00
|
|
|
}
|
2014-06-10 13:13:16 +00:00
|
|
|
|
2015-11-09 21:30:46 +00:00
|
|
|
void CanvasPortion::preparePixels() {
|
|
|
|
if (pixels) {
|
2014-08-18 15:16:17 +00:00
|
|
|
delete[] pixels;
|
|
|
|
}
|
2014-06-10 13:13:16 +00:00
|
|
|
pixels = new CanvasPixel[width * height];
|
|
|
|
}
|
|
|
|
|
2015-11-09 21:30:46 +00:00
|
|
|
void CanvasPortion::discardPixels(bool save) {
|
|
|
|
if (pixels) {
|
|
|
|
if (save) {
|
2014-08-21 07:58:11 +00:00
|
|
|
saveToDisk();
|
|
|
|
}
|
2014-08-18 15:33:15 +00:00
|
|
|
delete[] pixels;
|
|
|
|
pixels = NULL;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-11-09 21:30:46 +00:00
|
|
|
void CanvasPortion::saveToDisk() {
|
|
|
|
if (pixels) {
|
2015-11-18 21:22:09 +00:00
|
|
|
auto pid = System::getProcessId();
|
2015-12-10 23:36:50 +00:00
|
|
|
filepath = FileSystem::getTempFile("paysages_portion_" + to_string(index) + "_" + to_string(pid) + ".dat");
|
2014-08-21 07:58:11 +00:00
|
|
|
PackStream stream;
|
|
|
|
stream.bindToFile(filepath, true);
|
|
|
|
stream.write(&width);
|
|
|
|
stream.write(&height);
|
2015-11-09 21:30:46 +00:00
|
|
|
for (int y = 0; y < height; y++) {
|
|
|
|
for (int x = 0; x < width; x++) {
|
2014-08-21 07:58:11 +00:00
|
|
|
pixels[y * width + x].getComposite().save(&stream);
|
|
|
|
}
|
|
|
|
}
|
2015-11-18 21:22:09 +00:00
|
|
|
_files.push_back(filepath);
|
2014-08-21 07:58:11 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-11-09 21:30:46 +00:00
|
|
|
bool CanvasPortion::getReadStream(PackStream &stream, int x, int y) {
|
|
|
|
if (FileSystem::isFile(filepath)) {
|
|
|
|
if (not stream.bindToFile(filepath)) {
|
2014-08-21 13:30:09 +00:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2014-08-21 10:36:28 +00:00
|
|
|
int unused_i;
|
|
|
|
stream.skip(unused_i, 2);
|
2014-08-21 13:30:09 +00:00
|
|
|
|
2015-11-09 21:30:46 +00:00
|
|
|
if (x > 0 or y > 0) {
|
2014-08-21 13:30:09 +00:00
|
|
|
double unused_d;
|
|
|
|
stream.skip(unused_d, (y * width + x) * 4);
|
|
|
|
}
|
|
|
|
|
2014-08-21 10:36:28 +00:00
|
|
|
return true;
|
2015-11-09 21:30:46 +00:00
|
|
|
} else {
|
2014-08-21 10:36:28 +00:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-11-09 21:30:46 +00:00
|
|
|
void CanvasPortion::pushFragment(int x, int y, const CanvasFragment &fragment) {
|
2014-06-10 13:13:16 +00:00
|
|
|
CHECK_COORDINATES();
|
|
|
|
|
|
|
|
CanvasPixel &pixel = pixels[y * width + x];
|
2014-06-12 15:45:59 +00:00
|
|
|
Color old_color = pixel.getComposite();
|
|
|
|
|
2014-06-10 13:13:16 +00:00
|
|
|
pixel.pushFragment(fragment);
|
2014-06-12 15:45:59 +00:00
|
|
|
|
2015-11-09 21:30:46 +00:00
|
|
|
if (preview) {
|
2014-08-18 15:33:15 +00:00
|
|
|
preview->pushPixel(xoffset + x, yoffset + y, old_color, pixel.getComposite());
|
2014-06-12 15:45:59 +00:00
|
|
|
}
|
2014-06-05 15:12:49 +00:00
|
|
|
}
|
2014-08-18 10:17:16 +00:00
|
|
|
|
2015-11-09 21:30:46 +00:00
|
|
|
const CanvasPixel &CanvasPortion::at(int x, int y) {
|
2014-08-18 10:17:16 +00:00
|
|
|
CHECK_COORDINATES();
|
|
|
|
|
|
|
|
return pixels[y * width + x];
|
|
|
|
}
|
|
|
|
|
2015-11-09 21:30:46 +00:00
|
|
|
void CanvasPortion::setColor(int x, int y, const Color &color) {
|
2014-08-18 10:17:16 +00:00
|
|
|
CHECK_COORDINATES();
|
|
|
|
|
|
|
|
CanvasPixel &pixel = pixels[y * width + x];
|
|
|
|
Color old_color = pixel.getComposite();
|
|
|
|
|
|
|
|
pixel.setComposite(color);
|
|
|
|
|
2015-11-09 21:30:46 +00:00
|
|
|
if (preview) {
|
2014-08-18 15:33:15 +00:00
|
|
|
preview->pushPixel(xoffset + x, yoffset + y, old_color, pixel.getComposite());
|
2014-08-18 10:17:16 +00:00
|
|
|
}
|
|
|
|
}
|