diff --git a/main/main.cpp b/main/main.cpp index 1be5873..1e087b8 100644 --- a/main/main.cpp +++ b/main/main.cpp @@ -1,60 +1,35 @@ #include "../src/Bitmap.h" -#include "../src/Font.h" #include "../src/TextRenderer.h" #include -#include - -bool isQuit(const std::string& command); /** * @author: Julian Hinxlage * @since: v0.0.0 * @brief: An image is loaded and used as a font. - * A string is converted and displayed in the console. - * Currently only to test. */ -void outPutPixel(int windowHeight, int windowWidth, vkvm::Color fontColor); int main() { vkvm::initialize(0); - - std::string currentText; - - /**************************get text and font from shared memory*******************************************/ + vkvm::setLogLevel(vkvm::DEBUG); TextRenderer textRenderer = TextRenderer(); textRenderer.setLeftMargin(1); textRenderer.setBottomMargin(1); - /*************************get Text and update back to shared meomory********************************************/ + vkvm::registerEvent(vkvm::EventType::RenderText, [&textRenderer]() { std::string currentText = vkvm::getText(); + vkvm::log(vkvm::DEBUG, currentText); textRenderer.update(currentText); vkvm::callEvent(vkvm::EventType::Redraw); }); - - std::string command; - std::cout << "TextRender: "; - std::getline(std::cin, command); - while (command != "quit") { - if (command == "clear") { - textRenderer.clear(); - } if (command == "redblue") { - vkvm::setBackgroundColor(vkvm::red); - vkvm::setForegroundColor(vkvm::blue); - } else { - vkvm::setText(command); - currentText = vkvm::getText(); - textRenderer.update(currentText); - } - std::cout << "TextRender: "; - std::getline(std::cin, command); + vkvm::registerEvent(vkvm::EventType::UpdateControlRegisters, [&textRenderer]() { + textRenderer.updateParameters(); + }); + while (true) { } - - std::cout << "TextRender finished." << std::endl; - return 0; } \ No newline at end of file diff --git a/src/TextRenderer.cpp b/src/TextRenderer.cpp index a9abbda..7b6ab89 100644 --- a/src/TextRenderer.cpp +++ b/src/TextRenderer.cpp @@ -1,98 +1,269 @@ // // Created by my on 2019/11/16. // +#include #include "TextRenderer.h" -#include - - -TextRenderer::TextRenderer() = default; +TextRenderer::TextRenderer() { + updateParameters(); +} void TextRenderer::update(std::string newText) { - int startX = 0; - int startY = 0; + currentX = 0; + currentY = 0; int i; - std::string fontResourcePath = "../res/font" + std::to_string(vkvm::getFont()) + ".bmp"; - std::string fontConfigureFilePath = "../res/font" + std::to_string(vkvm::getFont()) + ".toml"; - font = Font(fontResourcePath, fontConfigureFilePath); - int fontNumbersInOneLine = vkvm::getWidth() / (font.width() + left_margin); + + int fontNumbersInOneLine = windowWidth / (font.width() + left_margin); + int space = 0; + int currentLine; std::vector> characterBitmap; + clear(); + newText = adjustText(newText); + + vkvm::log(vkvm::LogLevel::DEBUG, newText, "\n"); + for(i = 0; i < newText.size(); i++) { - if(i > oldText.size() || oldText[i] != newText[i]) { - startX = (i % fontNumbersInOneLine) * (font.width() + left_margin); - startY = (i / fontNumbersInOneLine) * (font.height() + bottom_margin); - characterBitmap = getCharacter(newText[i]); -// fontProcessing(characterBitmap); - translateToSharedMemory(characterBitmap, startX, startY); + + if(newText[i] == returnCharacter) { + space += (fontNumbersInOneLine - ((i + space) % fontNumbersInOneLine) - 1); + } else { + if(newText[i] == specialCharacter) { + space -= 1; + + int tempBlinkX = blinkX; + int tempBlinkY = blinkY; + int tempSpecialCharacterCurrentX = specialCharacterCurrentX; + int tempSpecialCharacterCurrentY = specialCharacterCurrentY; + char tempSpecialChar = _specialCharacter; + + specialCharacterCurrentX = ((i + space) % fontNumbersInOneLine) * (font.width() + left_margin); + specialCharacterCurrentY = ((i + space) / fontNumbersInOneLine) * (font.height() + bottom_margin); + + blinkX = specialCharacterCurrentX + font.width(); + blinkY = specialCharacterCurrentY; + _specialCharacter = newText[i - 1]; + + if(_specialCharacter != '\n') { + characterBitmap = getCharacter(_specialCharacter); + translateToSharedMemory(characterBitmap, specialCharacterCurrentX, specialCharacterCurrentY, true); + } else { + blinkX = 0; + blinkY += (font.height() + bottom_margin); + } + + if(specialCharacterCurrentX != tempSpecialCharacterCurrentX && specialCharacterCurrentY != tempSpecialCharacterCurrentY) { + clear(tempBlinkX, tempBlinkY, tempBlinkX + 1, tempBlinkY + font.height() + 1); + if(tempSpecialChar != '\n' && (tempSpecialCharacterCurrentY * 10 + tempSpecialCharacterCurrentX <= specialCharacterCurrentY * 10 + tempSpecialCharacterCurrentX)) { + translateToSharedMemory(getCharacter(tempSpecialChar), tempSpecialCharacterCurrentX, tempSpecialCharacterCurrentY, true); + } + } + } else { + currentLine = ((i + space) / fontNumbersInOneLine); + + currentX = ((i + space) % fontNumbersInOneLine) * (font.width() + left_margin); + currentY = (currentLine) * (font.height() + bottom_margin); + + characterBitmap = getCharacter(newText[i]); + + translateToSharedMemory(characterBitmap, currentX, currentY, false); + } + } + } + + if(newText.size() < oldTextsize) { + clear(currentX, currentY, font.width(), currentY + font.height()); + } +} + +std::string TextRenderer::adjustText(std::string newText) { + int fontNumbersInOneLine = windowWidth / (font.width() + left_margin); + int totalLine = windowHeight / (font.height() + bottom_margin); + int stringLine = 1; + int characterNumberOfLastLine = 0; + + for(char c : newText) { + if(c == returnCharacter) { + stringLine++; + characterNumberOfLastLine = 0; + } else if(c != specialCharacter) { + characterNumberOfLastLine++; + if(characterNumberOfLastLine == fontNumbersInOneLine) { + stringLine++; + characterNumberOfLastLine = 0; + } } } - setOldText(newText); + if(stringLine > totalLine) { + int startLine = stringLine - totalLine; + int currentLine = 0; + int cursorLine; + for(int i = 0; i < newText.size(); i++) { + if(newText[i] == returnCharacter) { + currentLine++; + characterNumberOfLastLine = 0; + } else if(newText[i] != specialCharacter) { + characterNumberOfLastLine++; + if(characterNumberOfLastLine == fontNumbersInOneLine) { + currentLine++; + characterNumberOfLastLine = 0; + } + } else { + cursorLine = currentLine; + + if(currentLine < startLine) { + return adjustText(newText, cursorLine, cursorLine + totalLine); + } + } + + if(currentLine == startLine) { + return newText.substr(i + 1, newText.size()); + } + } + } + + return newText; +} + +std::string TextRenderer::adjustText(std::string newText, int startLine, int endLine) { + int currentLine = 0; + int startIndex, endIndex; + int characterNumberOfCurrentLine = 0; + int fontNumbersInOneLine = windowWidth / (font.width() + left_margin); + + for(int i = 0; i < newText.size(); i++) { + if(newText[i] == returnCharacter) { + characterNumberOfCurrentLine = 0; + currentLine++; + + if(currentLine == startLine) { + startIndex = i; + } + + if(currentLine == endLine) { + endIndex = i; + + return newText.substr(startIndex + 1, endIndex); + } + } else if (newText[i] != specialCharacter) { + characterNumberOfCurrentLine++; + if(characterNumberOfCurrentLine == fontNumbersInOneLine) { + characterNumberOfCurrentLine = 0; + currentLine++; + + if(currentLine == startLine) { + startIndex = i; + } + + if(currentLine == endLine) { + endIndex = i; + + return newText.substr(startIndex + 1, endIndex); + } + } + } + } + + vkvm::log(vkvm::ERROR, "could not adjust string"); + return std::string(); } void TextRenderer::clear() { - int x; - int y; - for(y = 0; y < vkvm::getHeight(); y++) { - for(x = 0; x < vkvm::getWidth(); x++) { - vkvm::setPixel(x, y, vkvm::getBackgroundColor()); + clear(0, 0, windowWidth, windowHeight); +} + +void TextRenderer::clear(int startX, int startY, int endX, int endY) { + int x, y; + for(y = startY; y < endY; y++) { + for(x = startX; x < endX; x++) { + vkvm::setPixel(x, y, backgroundColor); } } } -void TextRenderer::setOldText(std::string text) { - oldText = std::move(text); -} std::vector> TextRenderer::getCharacter(unsigned char character) { - int fontHeight = font.height(); - int fontWidth = font.width(); - std::vector> bitmap_character; -// bitmap_character = (bool**)malloc(fontHeight * sizeof(bool*)); - bitmap_character.resize(fontHeight); - for (int i = 0; i < fontHeight; i++) { -// bitmap_character[i] = (bool*)malloc(fontWidth * sizeof(bool)); - bitmap_character[i].resize(fontWidth); - for (int j = 0; j < fontWidth; j++) { - bitmap_character[i][j] = font.getPixel(character, j, i); + std::vector> bitmap_character; + bitmap_character.resize(font.height()); + + vkvm::log(vkvm::DEBUG, bitmap_character.size()); + + for (int y = 0; y < font.height(); y += fontSize) { + vkvm::log(vkvm::DEBUG, y); + for(int i = 0; i < fontSize; i++) { + bitmap_character[y + i].resize(font.width()); + } + for (int x = 0; x < font.width(); x += fontSize) { + bitmap_character[y][x] = font.getPixel(character, x / fontSize, y / fontSize); + + if(bitmap_character[y][x] && fontSize != 1) { + + if(y != 0) { + for (int i = y - fontSize + 1; i < y; i++) { + bitmap_character[i][x] = bitmap_character[y - fontSize][x]; + } + } + + if(x != 0) { + for (int i = x - fontSize + 1; i < x; i++) { + bitmap_character[y][i] = bitmap_character[y][x - fontSize]; + } + } + + if(x != 0 && y != 0) { + for (int i = 1; i < fontSize; i++) { + bitmap_character[y - i][x - i] = bitmap_character[y - fontSize][x - fontSize]; + } + } + } } } - + vkvm::log(vkvm::DEBUG, bitmap_character.size()); return bitmap_character; } -void TextRenderer::translateToSharedMemory(std::vector> characterBitmap, int startX, int startY) { - int x; - int y; - int currentX = startX; - int currentY = startY; +void TextRenderer::translateToSharedMemory(std::vector> characterBitmap, int startX, int startY, bool flipColors) { + int x, y; + int _currentX = startX; + int _currentY = startY; + + for(y = 0; y < font.height(); y++) { for(x = 0; x < font.width(); x++) { if(characterBitmap[y][x]) { - vkvm::setPixel(currentX, currentY, vkvm::getForegroundColor()); + vkvm::log(vkvm::DEBUG, x, y); + if(flipColors) { + vkvm::setPixel(currentX, currentY, backgroundColor); + }else { + vkvm::setPixel(currentX, currentY, foregroundColor); + } } else { - vkvm::setPixel(currentX, currentY, vkvm::getBackgroundColor()); + if(flipColors) + vkvm::setPixel(currentX, currentY, foregroundColor); + else + vkvm::setPixel(currentX, currentY, backgroundColor); + } - currentX++; + _currentX++; } - currentX = startX; - currentY++; + _currentX = startX; + _currentY++; } for(x = 0; x < left_margin; x++) { for(y = 0; y < font.height(); y++) { - vkvm::setPixel(startX + font.width() + x, startY + y, vkvm::getBackgroundColor()); + vkvm::setPixel(startX + font.width() + x, startY + y, backgroundColor); } } for(y = 0; y < bottom_margin; y++) { for(x = 0; x < font.width() + left_margin; x++) { - vkvm::setPixel(startX + x, startY + font.height() + y, vkvm::getBackgroundColor()); + vkvm::setPixel(startX + x, startY + font.height() + y, backgroundColor); } } } @@ -104,3 +275,16 @@ void TextRenderer::setLeftMargin(int margin) { void TextRenderer::setBottomMargin(int margin) { bottom_margin = margin; } + +void TextRenderer::updateParameters() { + windowHeight = vkvm::getHeight(); + windowWidth = vkvm::getWidth(); + + int fontId = vkvm::getFont(); + std::string fontResourcePath = "../res/font" + std::to_string(fontId) + ".bmp"; + std::string fontConfigureFilePath = "../res/font" + std::to_string(fontId) + ".toml"; + font = Font(fontResourcePath, fontConfigureFilePath); + + backgroundColor = vkvm::getBackgroundColor(); + foregroundColor = vkvm::getForegroundColor(); +} \ No newline at end of file diff --git a/src/TextRenderer.h b/src/TextRenderer.h index bf73735..9354103 100644 --- a/src/TextRenderer.h +++ b/src/TextRenderer.h @@ -9,6 +9,7 @@ #include #include #include +#include #include /** @@ -19,21 +20,38 @@ class TextRenderer { public: TextRenderer(); - void update(std::string text); - void setOldText(std::string text); + void updateParameters(); std::vector> getCharacter(unsigned char character); void setLeftMargin(int margin); void setBottomMargin(int margin); void clear(); + void clear(int startX, int startY, int endX, int endY); private: - std::string oldText; int left_margin = 1; int bottom_margin = 1; - int type; Font font; - void translateToSharedMemory(std::vector> characterBitmap, int startX, int startY); + void translateToSharedMemory(std::vector> characterBitmap, int startX, int startY, bool flipColors); + vkvm::Color backgroundColor; + vkvm::Color foregroundColor; + int windowWidth; + int windowHeight; + + char returnCharacter = '\n'; + char specialCharacter = -127; + int specialCharacterCurrentX; + int specialCharacterCurrentY; + char _specialCharacter; + int fontSize = 1; + int currentX; + int currentY; + int oldTextsize{}; + int blinkX = 0; + int blinkY = 0; + + std::string adjustText(std::string newText); + std::string adjustText(std::string newText, int startLine, int endLine); };