Merge branch 'dev' into 'master'
Dev See merge request link/projekte/ws19/vkvm-new/text-renderer!8
This commit is contained in:
commit
762f8af5fe
|
@ -0,0 +1,32 @@
|
|||
#!/bin/sh
|
||||
|
||||
echo "Doing clang-tidy..."
|
||||
bool=false
|
||||
# explicitly set IFS to contain only a line feed
|
||||
IFS='
|
||||
'
|
||||
filelist="$(find . -not \( -path './*build*' -prune \) -not \( -path './include' -prune \) -type f ! -name "$(printf "*\n*")")"
|
||||
for file in $filelist; do
|
||||
if echo "$file" | grep -q -E ".*(\.cpp|\.hpp)$" ; then
|
||||
#Extra check missing dependencies due to clang-tidy doesn't toggle exit code.
|
||||
clang_tidy_lib_check="$(clang-tidy -warnings-as-errors='*' -header-filter='.*,-cpptoml.hpp' "$file" -- -I. -std=c++14 2>&1)"
|
||||
for tidy_line in $clang_tidy_lib_check; do
|
||||
echo "$tidy_line" | grep -q -v -E "^Error while processing*"
|
||||
if [ $? -eq 1 ]; then
|
||||
bool=true
|
||||
fi
|
||||
echo "$tidy_line" | grep -q -v -E ".* error: .*"
|
||||
if [ $? -eq 1 ]; then
|
||||
bool=true
|
||||
fi
|
||||
echo "$tidy_line"
|
||||
done
|
||||
fi
|
||||
done
|
||||
if $bool; then
|
||||
exit 1
|
||||
else
|
||||
echo "No clang-tidy errors found."
|
||||
fi
|
||||
|
||||
exit 0
|
|
@ -0,0 +1,2 @@
|
|||
Checks: '*,-llvm-header-guard,-fuchsia*,-cppcoreguidelines-pro-bounds-pointer-arithmetic,-cppcoreguidelines-pro-bounds-constant-array-index,-bugprone-narrowing-conversions,-cppcoreguidelines-narrowing-conversions,-cppcoreguidelines-pro-type-const-cast,-cppcoreguidelines-pro-type-reinterpret-cast,-hicpp-signed-bitwise,-bugprone-exception-escape,-cppcoreguidelines-pro-type-member-init,-cppcoreguidelines-pro-type-cstyle-cast,-hicpp-member-init,-google-readability-namespace-comments,-llvm-namespace-comment,-cppcoreguidelines-pro-type-vararg,-hicpp-vararg,-modernize-use-trailing-return-type,-readability-magic-numbers,-cppcoreguidelines-avoid-magic-numbers'
|
||||
WarningsAsErrors: 'true'
|
|
@ -0,0 +1,76 @@
|
|||
---
|
||||
|
||||
image: samueldebruyn/debian-git:latest
|
||||
|
||||
stages:
|
||||
- style
|
||||
- test
|
||||
- build
|
||||
|
||||
|
||||
clang_tidy:
|
||||
image: joethei/clang_tidy
|
||||
stage: style
|
||||
tags:
|
||||
- docker-ci
|
||||
script:
|
||||
- mkdir current
|
||||
- ls -d .[!.]* | grep -v current | xargs mv -t current
|
||||
- git clone https://gitlab-ci-token:${CI_JOB_TOKEN}@gitlab.repo.digitech.hs-emden-leer.de/link/projekte/ws19/vkvm-new/library.git
|
||||
- mkdir library/build
|
||||
- cd library/build
|
||||
- cmake ..
|
||||
- make
|
||||
- cd ../../current/.ci
|
||||
- sh clang-tidy.sh
|
||||
|
||||
make_test:
|
||||
stage: test
|
||||
tags:
|
||||
- docker-ci
|
||||
script:
|
||||
- apt-get update
|
||||
- apt-get install -y g++ make cmake clang-tidy
|
||||
- mkdir current
|
||||
- ls | grep -v current | xargs mv -t current
|
||||
- git clone https://github.com/catchorg/Catch2.git
|
||||
- cd Catch2
|
||||
- cmake -Bbuild -H. -DBUILD_TESTING=OFF
|
||||
- cmake --build build/ --target install
|
||||
- cd ..
|
||||
- git clone https://gitlab-ci-token:${CI_JOB_TOKEN}@gitlab.repo.digitech.hs-emden-leer.de/link/projekte/ws19/vkvm-new/library.git
|
||||
- mkdir library/build
|
||||
- cd library/build
|
||||
- cmake ..
|
||||
- make
|
||||
- cd ../../current
|
||||
- mkdir build
|
||||
- cd build
|
||||
- cmake ..
|
||||
- make
|
||||
- make test
|
||||
|
||||
cmake_build:
|
||||
stage: build
|
||||
tags:
|
||||
- docker-ci
|
||||
script:
|
||||
- apt-get update
|
||||
- apt-get install -y g++ make cmake clang-tidy
|
||||
- mkdir current
|
||||
- ls | grep -v current | xargs mv -t current
|
||||
- git clone https://github.com/catchorg/Catch2.git
|
||||
- cd Catch2
|
||||
- cmake -Bbuild -H. -DBUILD_TESTING=OFF
|
||||
- cmake --build build/ --target install
|
||||
- cd ..
|
||||
- git clone https://gitlab-ci-token:${CI_JOB_TOKEN}@gitlab.repo.digitech.hs-emden-leer.de/link/projekte/ws19/vkvm-new/library.git
|
||||
- mkdir library/build
|
||||
- cd library/build
|
||||
- cmake ..
|
||||
- make
|
||||
- cd ../../current
|
||||
- mkdir build
|
||||
- cd build
|
||||
- cmake ..
|
||||
- make
|
|
@ -12,11 +12,11 @@ project(TextRenderer)
|
|||
set(CMAKE_CXX_STANDARD 14)
|
||||
|
||||
# enable clang_tidy
|
||||
set(CMAKE_CXX_CLANG_TIDY "clang-tidy;-checks=*")
|
||||
set(CMAKE_CXX_CLANG_TIDY clang-tidy;-header-filter=.;-checks=*;)
|
||||
set(CMAKE_CXX_CLANG_TIDY "clang-tidy")
|
||||
set(CMAKE_CXX_CLANG_TIDY clang-tidy;-header-filter=.;)
|
||||
|
||||
file(GLOB_RECURSE SOURCES src/*.cpp)
|
||||
file(GLOB_RECURSE HEADERS src/*.h)
|
||||
file(GLOB_RECURSE HEADERS src/*.hpp)
|
||||
file(GLOB_RECURSE TESTS test/*.cpp)
|
||||
include_directories(src)
|
||||
include_directories(test)
|
||||
|
@ -30,12 +30,14 @@ include_directories(${LIB_PATH}/include)
|
|||
add_executable(TextRenderer ${SOURCES} ${HEADERS} main/main.cpp)
|
||||
|
||||
target_link_libraries(TextRenderer ${LIB_PATH}/lib/liblibrary.a)
|
||||
|
||||
target_link_libraries(TextRenderer pthread)
|
||||
|
||||
enable_testing()
|
||||
find_package(Catch2 REQUIRED)
|
||||
add_executable(UnitTests ${SOURCES} ${HEADERS} ${TESTS})
|
||||
target_link_libraries(UnitTests ${LIB_PATH}/lib/liblibrary.a)
|
||||
target_link_libraries(UnitTests Catch2::Catch2)
|
||||
target_link_libraries(UnitTests pthread)
|
||||
|
||||
include(CTest)
|
||||
include(Catch)
|
||||
|
|
39
README.md
39
README.md
|
@ -1,41 +1,14 @@
|
|||
# vKVM Text Renderer
|
||||
|
||||
The Text Renderer gets the string from the text area in the Shared Memory and writes it
|
||||
into pixelarea.
|
||||
|
||||
To convert a string the Text Renderer uses a font, which is loaded from a bitmap-file.
|
||||
|
||||
|
||||
## Installation
|
||||
|
||||
Use the installation script provided in the Scripts repository
|
||||
to install the full package.
|
||||
|
||||
Installing a single component is currently not supported.
|
||||
|
||||
## Target
|
||||
|
||||
TextRender build exports an interface target TextRender::TextRender.
|
||||
|
||||
This means that if TextRender has been installed on the Project Path, it
|
||||
should be enough to do.
|
||||
|
||||
translate a string from terminal to the readable form of shared memory .
|
||||
|
||||
## Usage
|
||||
|
||||
mkdir build
|
||||
cd build
|
||||
cmake ..
|
||||
make
|
||||
|
||||
## Description
|
||||
|
||||
TextRender has two class, Bitmap class and Font class.
|
||||
|
||||
res/font.bmp (bitmap data, used by Bitmap::load() function)
|
||||
|
||||
res/font.toml (configuration file, it configure how to read the font.bmp)
|
||||
|
||||
src/Bitmap class, it used to read the font.bmp file.
|
||||
|
||||
src/Font class, it read the font.bmp data by Bitmap class,
|
||||
translate a string to a bitmap.
|
||||
|
||||
test folder used to test.
|
||||
|
||||
main folder is only used to test now.
|
113
main/main.cpp
113
main/main.cpp
|
@ -1,36 +1,117 @@
|
|||
#include "add.h"
|
||||
#include "Bitmap.h"
|
||||
#include "Font.h"
|
||||
|
||||
#include "Font.hpp"
|
||||
#include "internal.hpp"
|
||||
#include "vkvm.hpp"
|
||||
#include <thread>
|
||||
#include <iostream>
|
||||
|
||||
int cursorPosX = 0;
|
||||
int cursorPosY = 0;
|
||||
bool showCursor = false;
|
||||
|
||||
/**
|
||||
* @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.
|
||||
*/
|
||||
int main() {
|
||||
Font font("../res/font2.bmp","../res/font2.toml");
|
||||
|
||||
std::string str;
|
||||
std::cout << "string to draw: ";
|
||||
std::getline(std::cin, str);
|
||||
void threadHandler(Font &font){
|
||||
static bool cursorState{false};
|
||||
|
||||
int start = 0;
|
||||
int end = font.height();
|
||||
auto bc = vkvm::getBackgroundColor();
|
||||
auto fc = vkvm::getForegroundColor();
|
||||
|
||||
while(true){
|
||||
if(showCursor) {
|
||||
int x = cursorPosX - 1;
|
||||
if (x < 0) {
|
||||
x = 0;
|
||||
}
|
||||
|
||||
for (int i = start; i < end; i++) {
|
||||
if (cursorState) {
|
||||
vkvm::setPixel(x, cursorPosY + i, bc);
|
||||
} else {
|
||||
vkvm::setPixel(x, cursorPosY + i, fc);
|
||||
}
|
||||
}
|
||||
vkvm::callEvent(vkvm::EventType::Redraw);
|
||||
cursorState = !cursorState;
|
||||
}
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(800));
|
||||
}
|
||||
}
|
||||
|
||||
int main() {
|
||||
vkvm::initialize(0);
|
||||
vkvm::setLogLevel(vkvm::DEBUG);
|
||||
|
||||
Font font(
|
||||
std::string() + "../res/font" +
|
||||
std::to_string(static_cast<int>(vkvm::getFont())) + ".bmp",
|
||||
std::string() + "../res/font" +
|
||||
std::to_string(static_cast<int>(vkvm::getFont())) + ".toml");
|
||||
|
||||
std::thread thread(std::bind(threadHandler, font));
|
||||
|
||||
vkvm::registerEvent(vkvm::EventType::RenderText, [&font]() {
|
||||
std::string currentText = vkvm::getText();
|
||||
int perRow = vkvm::getWidth() / font.width();
|
||||
auto bc = vkvm::getBackgroundColor();
|
||||
auto fc = vkvm::getForegroundColor();
|
||||
|
||||
//clear area
|
||||
for(int y = 0; y < vkvm::getHeight();y++){
|
||||
for(int x = 0; x < vkvm::getWidth();x++) {
|
||||
vkvm::setPixel(x,y,bc);
|
||||
}
|
||||
}
|
||||
|
||||
showCursor = false;
|
||||
int x = 0;
|
||||
int y = 0;
|
||||
for(char c : currentText){
|
||||
if(c == '\n'){
|
||||
y++;
|
||||
x = 0;
|
||||
}else if(c == -127){
|
||||
cursorPosX = x * font.width();
|
||||
cursorPosY = y * font.height();
|
||||
showCursor = true;
|
||||
}
|
||||
else{
|
||||
if(x == perRow){
|
||||
y++;
|
||||
x = 0;
|
||||
}
|
||||
|
||||
for(int i = 0; i < font.height();i++){
|
||||
for (char c : str) {
|
||||
for(int j = 0; j < font.width();j++){
|
||||
if(font.getPixel(c, j, i)){
|
||||
std::cout << "█";
|
||||
vkvm::setPixel(x * font.width() + j, y * font.height() + i, fc);
|
||||
}else{
|
||||
std::cout << " ";
|
||||
vkvm::setPixel(x * font.width() + j, y * font.height() + i, bc);
|
||||
}
|
||||
}
|
||||
std::cout << " ";
|
||||
}
|
||||
std::cout << std::endl;
|
||||
x++;
|
||||
}
|
||||
}
|
||||
|
||||
vkvm::callEvent(vkvm::EventType::Redraw);
|
||||
});
|
||||
|
||||
vkvm::registerEvent(vkvm::EventType::UpdateControlRegisters, [&font]() {
|
||||
font.load(
|
||||
std::string() + "../res/font" +
|
||||
std::to_string(static_cast<int>(vkvm::getFont())) + ".bmp",
|
||||
std::string() + "../res/font" +
|
||||
std::to_string(static_cast<int>(vkvm::getFont())) + ".toml");
|
||||
});
|
||||
|
||||
while (true) {
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(100));
|
||||
}
|
||||
return 0;
|
||||
}
|
Binary file not shown.
After Width: | Height: | Size: 933 KiB |
|
@ -0,0 +1,12 @@
|
|||
xOffset = 6
|
||||
yOffset = 6
|
||||
xSize = 18
|
||||
ySize = 27
|
||||
xCount = 32
|
||||
yCount = 9
|
||||
xStart = 7
|
||||
yStart = 9
|
||||
fillValue = 4294967295
|
||||
firstChar = 25
|
||||
pixelSize = 1
|
||||
invertedColors = 1
|
Binary file not shown.
After Width: | Height: | Size: 2.0 MiB |
|
@ -0,0 +1,12 @@
|
|||
xOffset = 6
|
||||
yOffset = 2
|
||||
xSize = 10
|
||||
ySize = 14
|
||||
xCount = 255
|
||||
yCount = 255
|
||||
xStart = 33
|
||||
yStart = 65
|
||||
fillValue = 0
|
||||
firstChar = 0
|
||||
pixelSize = 1
|
||||
invertedColors = 0
|
|
@ -1,4 +1,4 @@
|
|||
#include "Bitmap.h"
|
||||
#include "Bitmap.hpp"
|
||||
#include <fstream>
|
||||
#include <iostream>
|
||||
|
||||
|
@ -26,11 +26,10 @@ void Bitmap::load(const std::string &file) {
|
|||
for(int i = 0; i < str.size();i++){
|
||||
data[i] = str[i];
|
||||
}
|
||||
|
||||
offset = (int)*(unsigned int*)(&data[10]);
|
||||
width = (int)*(unsigned int*)(&data[18]);
|
||||
height = (int)*(unsigned int*)(&data[22]);
|
||||
bpp = (int)*(unsigned short*)(&data[28]);
|
||||
offset = *reinterpret_cast<int*>(&data[10]);
|
||||
width = *reinterpret_cast<int*>(&data[18]);
|
||||
height = *reinterpret_cast<int*>(&data[22]);
|
||||
bpp = *reinterpret_cast<uint16_t *>(&data[28]);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -52,12 +51,18 @@ int Bitmap::getBitsPerPixel() {
|
|||
|
||||
unsigned int Bitmap::getPixel(int x, int y) {
|
||||
unsigned int pixel = 0;
|
||||
|
||||
if(bpp == 1){
|
||||
int index = (getHeight() - 1 - y) * getWidth() + x;
|
||||
char *ptr = getData() + (index / 8);
|
||||
bool value = (ptr[0] >> (7 - (index % 8))) & 1u;
|
||||
return (int)value;
|
||||
}
|
||||
|
||||
char *ptr = getData() + ((getHeight() - 1 - y) * getWidth() + x) * (getBitsPerPixel() / 8);
|
||||
for(int i = 0; i < getBitsPerPixel() / 8;i++){
|
||||
*((char*)&pixel+i) = ptr[i];
|
||||
}
|
||||
if(pixel != 0){
|
||||
return pixel;
|
||||
auto value = reinterpret_cast<char*>(&pixel)+i;
|
||||
*value = ptr[i];
|
||||
}
|
||||
return pixel;
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
#ifndef TEXTRENDERER_BITMAP_H
|
||||
#define TEXTRENDERER_BITMAP_H
|
||||
#ifndef TEXTRENDERER_BITMAP_HPP
|
||||
#define TEXTRENDERER_BITMAP_HPP
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
@ -65,4 +65,4 @@ private:
|
|||
};
|
||||
|
||||
|
||||
#endif //TEXTRENDERER_BITMAP_H
|
||||
#endif //TEXTRENDERER_BITMAP_HPP
|
13
src/Font.cpp
13
src/Font.cpp
|
@ -2,8 +2,8 @@
|
|||
// Copyright (c) 2019 Julian Hinxlage. All rights reserved.
|
||||
//
|
||||
|
||||
#include "Font.h"
|
||||
#include <cpptoml.h>
|
||||
#include "Font.hpp"
|
||||
#include "../lib/toml/cpptoml.h"
|
||||
|
||||
Font::Font() {
|
||||
xOffset = 0;
|
||||
|
@ -16,6 +16,9 @@ Font::Font() {
|
|||
yStart = 0;
|
||||
fillValue = 0;
|
||||
firstChar = ' ';
|
||||
pixelSize = 1;
|
||||
gap = -1;
|
||||
invertedColors = false;
|
||||
}
|
||||
|
||||
Font::Font(const std::string &file, const std::string &configFile) : Font() {
|
||||
|
@ -34,9 +37,10 @@ void Font::load(const std::string &file, const std::string &configFile) {
|
|||
xStart = config->get_as<int>("xStart").value_or(0);
|
||||
yStart = config->get_as<int>("yStart").value_or(0);
|
||||
fillValue = config->get_as<unsigned int>("fillValue").value_or(0);
|
||||
firstChar = (char)config->get_as<int>("firstChar").value_or(0);
|
||||
firstChar = config->get_as<char>("firstChar").value_or(0);
|
||||
pixelSize = config->get_as<int>("pixelSize").value_or(0);
|
||||
gap = config->get_as<int>("gap").value_or(-1);
|
||||
invertedColors = static_cast<bool>(config->get_as<int>("invertedColors").value_or(0));
|
||||
}
|
||||
|
||||
int Font::width() {
|
||||
|
@ -69,6 +73,7 @@ bool Font::getPixel(char character, int x, int y) {
|
|||
int xPos = xIndex * (xSize + xOffset) + xStart;
|
||||
int yPos = yIndex * (ySize + yOffset) + yStart;
|
||||
|
||||
return bitmap.getPixel((xPos + x) * pixelSize, (yPos + y) * pixelSize) == fillValue;
|
||||
bool value = bitmap.getPixel((xPos + x) * pixelSize, (yPos + y) * pixelSize) == fillValue;
|
||||
return invertedColors != value;
|
||||
}
|
||||
|
||||
|
|
|
@ -2,10 +2,10 @@
|
|||
// Copyright (c) 2019 Julian Hinxlage. All rights reserved.
|
||||
//
|
||||
|
||||
#ifndef TEXTRENDERER_FONT_H
|
||||
#define TEXTRENDERER_FONT_H
|
||||
#ifndef TEXTRENDERER_FONT_HPP
|
||||
#define TEXTRENDERER_FONT_HPP
|
||||
|
||||
#include "Bitmap.h"
|
||||
#include "Bitmap.hpp"
|
||||
|
||||
/**
|
||||
* @author: Julian Hinxlage
|
||||
|
@ -13,7 +13,7 @@
|
|||
* @brief: this class provides pixel access based on characters
|
||||
*/
|
||||
class Font {
|
||||
public:
|
||||
private:
|
||||
Bitmap bitmap;
|
||||
|
||||
//space between characters
|
||||
|
@ -38,6 +38,10 @@ public:
|
|||
int pixelSize;
|
||||
int gap;
|
||||
|
||||
bool invertedColors;
|
||||
|
||||
public:
|
||||
|
||||
Font();
|
||||
explicit Font(const std::string &file, const std::string &configFile);
|
||||
void load(const std::string &file, const std::string &configFile);
|
||||
|
@ -48,4 +52,4 @@ public:
|
|||
};
|
||||
|
||||
|
||||
#endif //TEXTRENDERER_FONT_H
|
||||
#endif //TEXTRENDERER_FONT_HPP
|
|
@ -1,6 +1,6 @@
|
|||
#include "Bitmap.hpp"
|
||||
#include "Font.hpp"
|
||||
#include <catch2/catch.hpp>
|
||||
#include "Bitmap.h"
|
||||
#include "Font.h"
|
||||
|
||||
TEST_CASE("default values") {
|
||||
Bitmap bitmap = Bitmap();
|
||||
|
@ -20,7 +20,7 @@ TEST_CASE("Font") {
|
|||
Font font("../res/font1.bmp", "../res/font1.toml");
|
||||
REQUIRE(font.width() == 5);
|
||||
REQUIRE(font.height() == 7);
|
||||
REQUIRE(!font.getPixel('a', 1,1));
|
||||
REQUIRE_FALSE(font.getPixel('a', 1,1));
|
||||
REQUIRE(font.getPixel('a', 1,2));
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue