275 lines
8.1 KiB
C++
275 lines
8.1 KiB
C++
//
|
|
// Created by shaohuatong on 28.11.19.
|
|
//
|
|
|
|
#include "DrawRender.hpp"
|
|
#include <algorithm>
|
|
|
|
DrawRender::DrawRender(int windowWidth, int windowHeight, vkvm::Color defaultBackgroundColor, vkvm::Color penColor, int penWidth)
|
|
: backgroundColor(defaultBackgroundColor), penColor(penColor) {
|
|
this-> windowWidth = windowWidth;
|
|
this-> windowHeight = windowHeight;
|
|
this-> penWidth = penWidth;
|
|
}
|
|
|
|
void DrawRender::graphicsUpdate(int type) {
|
|
if(type == CIRCLE || type == SQUARE) {
|
|
std::vector<std::vector<bool>> graphics = circleAndSquareCreator(type);
|
|
translateToSharedMemory(graphics, startX, startY);
|
|
}
|
|
else if(type == RECTANGLE) {
|
|
std::vector<std::vector<bool>> graphics = rectangleCreator();
|
|
translateToSharedMemory(graphics, startX, startY);
|
|
}
|
|
|
|
}
|
|
|
|
void DrawRender::brushUpdate(vkvm::Coordinates mousePosition) {
|
|
std::vector<std::vector<bool>> brush = brushCreator(mousePosition);
|
|
translateToSharedMemory(brush, startX, startY);
|
|
}
|
|
|
|
void DrawRender::clear() {
|
|
int x, y;
|
|
for(y = 0; y < windowHeight; y++) {
|
|
for(x = 0; x < windowWidth; x++) {
|
|
vkvm::setPixel(x, y, backgroundColor);
|
|
}
|
|
}
|
|
}
|
|
std::vector<std::vector<bool>> DrawRender::rectangleCreator() {
|
|
if(painting == true)
|
|
clearToSharedMemory(oldGraphics, startX, startY);
|
|
|
|
int x_draw = 0;
|
|
int y_draw = 0;
|
|
std::vector<std::vector<bool>> rectangle;
|
|
length = abs(mouseLeftDownPosition.x - mousePosition.x);
|
|
width = abs(mouseLeftDownPosition.y - mousePosition.y);
|
|
vkvm::Coordinates uperLeft;
|
|
vkvm::Coordinates bottomRight;
|
|
uperLeft.x = min(mouseLeftDownPosition.x, mousePosition.x);
|
|
uperLeft.y = min(mouseLeftDownPosition.y, mousePosition.y);
|
|
bottomRight.x = max(mouseLeftDownPosition.x, mousePosition.x);
|
|
bottomRight.y = max(mouseLeftDownPosition.y, mousePosition.y);
|
|
|
|
rectangle.resize(width);
|
|
for(y_draw = 0; y_draw < width; y_draw++) {
|
|
rectangle[y_draw].resize(length);
|
|
for(x_draw = 0; x_draw < length; x_draw++) {
|
|
if((x_draw >= 0 && x_draw <= penWidth) || (y_draw >= 0 && y_draw <= penWidth)
|
|
|| (x_draw <= length && x_draw >= length - penWidth)
|
|
|| (y_draw <= width && y_draw >= width - penWidth)) {
|
|
rectangle[y_draw][x_draw] = true;
|
|
}
|
|
}
|
|
}
|
|
|
|
oldGraphics.resize(width);
|
|
for(y_draw = 0; y_draw < width; y_draw++) {
|
|
oldGraphics[y_draw].resize(length);
|
|
for(x_draw = 0; x_draw < length; x_draw++) {
|
|
oldGraphics[y_draw][x_draw] = true;
|
|
}
|
|
}
|
|
|
|
painting = true;
|
|
startX = uperLeft.x;
|
|
startY = uperLeft.y;
|
|
return rectangle;
|
|
}
|
|
std::vector<std::vector<bool>> DrawRender::circleAndSquareCreator(int type) {
|
|
if(painting == true)
|
|
clearToSharedMemory(oldGraphics, startX, startY);
|
|
std::vector<std::vector<bool>> circle;
|
|
int x_draw = 0;
|
|
int y_draw = 0;
|
|
int distance = 0;
|
|
radius = getDistance(getMouseLeftDownPosition(), getMousePostion()) / 2;
|
|
vkvm::Coordinates middlePosition;
|
|
middlePosition.x = (mousePosition.x + mouseLeftDownPosition.x) / 2;
|
|
middlePosition.y = (mousePosition.y + mouseLeftDownPosition.y) / 2;
|
|
|
|
vkvm::Coordinates uperLeft;
|
|
vkvm::Coordinates bottomRight;
|
|
uperLeft.x = middlePosition.x - radius;
|
|
uperLeft.y = middlePosition.y - radius;
|
|
bottomRight.x = middlePosition.x + radius;
|
|
bottomRight.y = middlePosition.y + radius;
|
|
|
|
vkvm::Coordinates temp;
|
|
circle.resize(2 * radius);
|
|
for(y_draw = 0; y_draw < 2 * radius; y_draw++) {
|
|
circle[y_draw].resize(2 * radius);
|
|
for(x_draw = 0; x_draw < 2 * radius; x_draw++) {
|
|
if(type == CIRCLE) {
|
|
temp.x = uperLeft.x + x_draw;
|
|
temp.y = uperLeft.y + y_draw;
|
|
distance = squareOfDistance(temp, middlePosition);
|
|
|
|
if( distance < (radius * radius) && distance > ((radius - penWidth) * (radius - penWidth))) {
|
|
circle[y_draw][x_draw] = true;
|
|
}
|
|
}
|
|
if(type == SQUARE) {
|
|
if((x_draw >= 0 && x_draw <= penWidth) || (y_draw >= 0 && y_draw <= penWidth)
|
|
|| (x_draw <= 2 * radius && x_draw >= 2 * radius - penWidth)
|
|
|| (y_draw <= 2 * radius && y_draw >= 2 * radius - penWidth)) {
|
|
circle[y_draw][x_draw] = true;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
oldGraphics.resize(2 * radius);
|
|
for(y_draw = 0; y_draw < 2 * radius; y_draw++) {
|
|
oldGraphics[y_draw].resize(2 * radius);
|
|
for(x_draw = 0; x_draw < 2 * radius; x_draw++) {
|
|
oldGraphics[y_draw][x_draw] = true;
|
|
}
|
|
}
|
|
|
|
painting = true;
|
|
startX = uperLeft.x;
|
|
startY = uperLeft.y;
|
|
return circle;
|
|
}
|
|
|
|
std::vector<std::vector<bool>> DrawRender::brushCreator(vkvm::Coordinates mousePosition) {
|
|
std::vector<std::vector<bool>> circleBrush;
|
|
int x_draw = 0;
|
|
int y_draw = 0;
|
|
int distance = 0;
|
|
radius = penWidth;
|
|
vkvm::Coordinates uperLeft;
|
|
vkvm::Coordinates bottomRight;
|
|
uperLeft.x = mousePosition.x - radius;
|
|
uperLeft.y = mousePosition.y - radius;
|
|
bottomRight.x = mousePosition.x + radius;
|
|
bottomRight.y = mousePosition.y + radius;
|
|
|
|
vkvm::Coordinates temp;
|
|
circleBrush.resize(2 * radius);
|
|
for(y_draw = 0; y_draw < 2 * radius; y_draw++) {
|
|
circleBrush[y_draw].resize(2 * radius);
|
|
for(x_draw = 0; x_draw < 2 * radius; x_draw++) {
|
|
temp.x = uperLeft.x + x_draw;
|
|
temp.y = uperLeft.y + y_draw;
|
|
distance = squareOfDistance(temp, mousePosition);
|
|
if( distance < (radius * radius)) {
|
|
circleBrush[y_draw][x_draw] = true;
|
|
}
|
|
}
|
|
}
|
|
|
|
startX = uperLeft.x;
|
|
startY = uperLeft.y;
|
|
return circleBrush;
|
|
}
|
|
|
|
|
|
void DrawRender::translateToSharedMemory(std::vector<std::vector<bool>> graphics, int startX, int startY) {
|
|
int x, y;
|
|
int currentX = startX;
|
|
int currentY = startY;
|
|
|
|
for(y = 0; y < graphics.size(); y++) {
|
|
for(x = 0; x < graphics[y].size(); x++) {
|
|
if(graphics[y][x]) {
|
|
vkvm::setPixel(currentX, currentY, penColor);
|
|
}
|
|
currentX++;
|
|
}
|
|
currentX = startX;
|
|
currentY++;
|
|
}
|
|
}
|
|
|
|
void DrawRender::clearToSharedMemory(std::vector<std::vector<bool>> graphics, int startX, int startY) {
|
|
int x, y;
|
|
int currentX = startX;
|
|
int currentY = startY;
|
|
|
|
for(y = 0; y < graphics.size(); y++) {
|
|
for(x = 0; x < graphics[y].size(); x++) {
|
|
if(graphics[y][x]) {
|
|
vkvm::setPixel(currentX, currentY, backgroundColor);
|
|
}
|
|
currentX++;
|
|
}
|
|
currentX = startX;
|
|
currentY++;
|
|
}
|
|
}
|
|
|
|
int DrawRender::squareOfDistance(vkvm::Coordinates x, vkvm::Coordinates y) {
|
|
return (x.x - y.x) * (x.x - y.x) + (x.y - y.y) * (x.y - y.y);
|
|
}
|
|
|
|
int DrawRender::getDistance(vkvm::Coordinates x, vkvm::Coordinates y) {
|
|
return (int)floor(sqrt(squareOfDistance(x, y)));
|
|
}
|
|
|
|
int DrawRender::min(int x, int y) {
|
|
if(x <= y)
|
|
return x;
|
|
return y;
|
|
}
|
|
|
|
int DrawRender::max(int x, int y) {
|
|
if(x<=y)
|
|
return y;
|
|
return x;
|
|
}
|
|
|
|
vkvm::Coordinates DrawRender::getMouseLeftDownPosition() {
|
|
return mouseLeftDownPosition;
|
|
}
|
|
|
|
void DrawRender::setMouseLeftDownPostion(vkvm::Coordinates newMousePosition) {
|
|
mouseLeftDownPosition = newMousePosition;
|
|
}
|
|
|
|
vkvm::Coordinates DrawRender::getMousePostion() {
|
|
return mousePosition;
|
|
}
|
|
|
|
void DrawRender::setMousePostion(vkvm::Coordinates newMousePosition) {
|
|
mousePosition = newMousePosition;
|
|
}
|
|
|
|
void DrawRender::setKeyCode(vkvm::KeyCode newKeyCode) {
|
|
keyCode = newKeyCode;
|
|
}
|
|
|
|
vkvm::KeyCode DrawRender::getKeyCode() {
|
|
return keyCode;
|
|
}
|
|
|
|
void DrawRender::setTurnOnBrush(bool newTurnOnBrush) {
|
|
turnOnBrush = newTurnOnBrush;
|
|
}
|
|
|
|
bool DrawRender::getTurnOnBrush() {
|
|
return turnOnBrush;
|
|
}
|
|
|
|
int DrawRender::getRadius() {
|
|
return radius;
|
|
}
|
|
|
|
bool DrawRender::getMouseDown() {
|
|
return mouseDown;
|
|
}
|
|
|
|
void DrawRender::setMouseDown(bool isMouseDown) {
|
|
mouseDown = isMouseDown;
|
|
}
|
|
|
|
bool DrawRender::getPainting() {
|
|
return painting;
|
|
}
|
|
|
|
void DrawRender::setPainting(bool isPainting) {
|
|
painting = isPainting;
|
|
} |