Merge branch 'dev' into 'master'

Merge dev into master

See merge request link/projekte/ws19/vkvm-new/text-renderer!2
This commit is contained in:
Julian Hinxlage 2019-11-02 11:03:17 +00:00
commit 8defbe8bfd
14 changed files with 3910 additions and 62 deletions

1
.gitignore vendored
View File

@ -10,6 +10,5 @@ CmakeCache.txt
bin/ bin/
lib/
include/ include/
build/ build/

View File

@ -21,6 +21,9 @@ file(GLOB_RECURSE TESTS test/*.cpp)
include_directories(src) include_directories(src)
include_directories(test) include_directories(test)
#toml
include_directories(lib/toml)
set(LIB_PATH "${CMAKE_SOURCE_DIR}/../library") set(LIB_PATH "${CMAKE_SOURCE_DIR}/../library")
include_directories(${LIB_PATH}/include) include_directories(${LIB_PATH}/include)

View File

@ -7,3 +7,35 @@ to install the full package.
Installing a single component is currently not supported. 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.

3668
lib/toml/cpptoml.h Normal file

File diff suppressed because it is too large Load Diff

View File

@ -1,7 +1,8 @@
#include <iostream>
#include "add.h" #include "add.h"
#include "Bitmap.h" #include "Bitmap.h"
#include "Font.h"
#include <iostream>
/** /**
* @author: Julian Hinxlage * @author: Julian Hinxlage
@ -11,50 +12,20 @@
* Currently only to test. * Currently only to test.
*/ */
int main() { int main() {
Bitmap bitmap; Font font("../res/font2.bmp","../res/font2.toml");
bitmap.load("../res/font.bmp");
std::string str; std::string str;
std::cout << "string to draw: "; std::cout << "string to draw: ";
std::cin >> str; std::getline(std::cin, str);
//values used to calculate the coordinates of the characters for (int i = 0; i < font.height(); i++) {
int xOffset = 2;
int yOffset = 2;
int xSize = 5;
int ySize = 7;
int xCount = 18;
int xStart = 1;
int yStart = 2;
//print vertical
//i is the current row
for (int i = 0; i < ySize; i++) {
//loop through the characters in the string
for (char c : str) { for (char c : str) {
//index of character(x and y) for (int j = 0; j < font.width(); j++) {
int index = (c - ' '); if (font.getPixel(c,j,i)) {
int xIndex = index % xCount; std::cout << "";
int yIndex = index / xCount;
//character index to pixel index conversion
int x = xIndex * (xSize + xOffset) + xStart;
int y = yIndex * (ySize + yOffset) + yStart;
//print current row of the current character
for (int j = x; j < x + xSize; j++) {
char *pixel_ptr = bitmap.getPixel(j, i + y);
unsigned int pixel = 0;
*((char*)&pixel+0) = pixel_ptr[0];
*((char*)&pixel+1) = pixel_ptr[1];
*((char*)&pixel+2) = pixel_ptr[2];
if (pixel == 0) {
std::cout << " ";
} else { } else {
std::cout << "1"; std::cout << " ";
} }
} }
std::cout << " "; std::cout << " ";
} }

View File

Before

Width:  |  Height:  |  Size: 24 KiB

After

Width:  |  Height:  |  Size: 24 KiB

11
res/font1.toml Normal file
View File

@ -0,0 +1,11 @@
xOffset = 2
yOffset = 2
xSize = 5
ySize = 7
xCount = 18
yCount = 4
xStart = 1
yStart = 1
fillValue = 0xffffff
firstChar = 32
pixelSize = 1

BIN
res/font2.bmp Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 384 KiB

13
res/font2.toml Normal file
View File

@ -0,0 +1,13 @@
xOffset = 0
yOffset = 0
xSize = 8
ySize = 8
xCount = 16
yCount = 6
xStart = 0
yStart = 16
fillValue = 0xffffff
firstChar = 33
pixelSize = 4
#gap is a character that will get skipped
gap = 63

View File

@ -7,29 +7,30 @@ Bitmap::Bitmap() {
width = 0; width = 0;
height = 0; height = 0;
bpp = 0; bpp = 0;
data = nullptr;
} }
Bitmap::~Bitmap() { Bitmap::Bitmap(const std::string &file) {
if(data){ offset = 0;
delete data; width = 0;
data = nullptr; height = 0;
} bpp = 0;
load(file);
} }
void Bitmap::load(const std::string &file) { void Bitmap::load(const std::string &file) {
std::ifstream stream(file); std::ifstream stream;
stream.open(file);
if(stream.is_open()){ if(stream.is_open()){
std::string str((std::istreambuf_iterator<char>(stream)),std::istreambuf_iterator<char>()); std::string str((std::istreambuf_iterator<char>(stream)),std::istreambuf_iterator<char>());
data = new char[str.size()]; data.resize(str.size());
for(int i = 0; i < str.size();i++){ for(int i = 0; i < str.size();i++){
data[i] = str[i]; data[i] = str[i];
} }
offset = *(unsigned int*)(data + 10); offset = (int)*(unsigned int*)(&data[10]);
width = *(unsigned int*)(data + 18); width = (int)*(unsigned int*)(&data[18]);
height = *(unsigned int*)(data + 22); height = (int)*(unsigned int*)(&data[22]);
bpp = *(unsigned short*)(data + 28); bpp = (int)*(unsigned short*)(&data[28]);
} }
} }
@ -42,13 +43,21 @@ int Bitmap::getHeight() {
} }
char *Bitmap::getData() { char *Bitmap::getData() {
return data + offset; return &data[offset];
} }
int Bitmap::getBitsPerPixel() { int Bitmap::getBitsPerPixel() {
return bpp; return bpp;
} }
char *Bitmap::getPixel(int x, int y) { unsigned int Bitmap::getPixel(int x, int y) {
return getData() + ((getHeight() - y) * getWidth() + x) * getBitsPerPixel() / 8; unsigned int pixel = 0;
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;
}
return pixel;
} }

View File

@ -2,6 +2,7 @@
#define TEXTRENDERER_BITMAP_H #define TEXTRENDERER_BITMAP_H
#include <string> #include <string>
#include <vector>
/** /**
* @author: Julian Hinxlage * @author: Julian Hinxlage
@ -11,8 +12,7 @@
class Bitmap { class Bitmap {
public: public:
Bitmap(); Bitmap();
explicit Bitmap(const std::string &file);
~Bitmap();
/** /**
* @author: Julian Hinxlage * @author: Julian Hinxlage
@ -54,14 +54,14 @@ public:
* @since: v0.0.0 * @since: v0.0.0
* @return: the pixel value by coordinates, (0,0) is on the top left * @return: the pixel value by coordinates, (0,0) is on the top left
*/ */
char *getPixel(int x, int y); unsigned int getPixel(int x, int y);
private: private:
int width; int width;
int height; int height;
int offset; int offset;
int bpp; int bpp;
char *data; std::vector<char> data;
}; };

74
src/Font.cpp Normal file
View File

@ -0,0 +1,74 @@
//
// Copyright (c) 2019 Julian Hinxlage. All rights reserved.
//
#include "Font.h"
#include <cpptoml.h>
Font::Font() {
xOffset = 0;
yOffset = 0;
xSize = 0;
ySize = 0;
xCount = 0;
yCount = 0;
xStart = 0;
yStart = 0;
fillValue = 0;
firstChar = ' ';
}
Font::Font(const std::string &file, const std::string &configFile) : Font() {
load(file, configFile);
}
void Font::load(const std::string &file, const std::string &configFile) {
bitmap.load(file);
auto config = cpptoml::parse_file(configFile);
xOffset = config->get_as<int>("xOffset").value_or(0);
yOffset = config->get_as<int>("yOffset").value_or(0);
xSize = config->get_as<int>("xSize").value_or(0);
ySize = config->get_as<int>("ySize").value_or(0);
xCount = config->get_as<int>("xCount").value_or(0);
yCount = config->get_as<int>("yOffset").value_or(0);
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);
pixelSize = config->get_as<int>("pixelSize").value_or(0);
gap = config->get_as<int>("gap").value_or(-1);
}
int Font::width() {
return xSize;
}
int Font::height() {
return ySize;
}
bool Font::getPixel(char character, int x, int y) {
//index of character(x and y)
int index = (character - firstChar);
if(gap != -1){
if (index >= gap){
index++;
}
}
int xIndex = index % xCount;
int yIndex = index / xCount;
if(index < 0){
yIndex--;
xIndex += xCount;
}
//character index to pixel index conversion
int xPos = xIndex * (xSize + xOffset) + xStart;
int yPos = yIndex * (ySize + yOffset) + yStart;
return bitmap.getPixel((xPos + x) * pixelSize, (yPos + y) * pixelSize) == fillValue;
}

51
src/Font.h Normal file
View File

@ -0,0 +1,51 @@
//
// Copyright (c) 2019 Julian Hinxlage. All rights reserved.
//
#ifndef TEXTRENDERER_FONT_H
#define TEXTRENDERER_FONT_H
#include "Bitmap.h"
/**
* @author: Julian Hinxlage
* @since: v0.0.0
* @brief: this class provides pixel access based on characters
*/
class Font {
public:
Bitmap bitmap;
//space between characters
int xOffset;
int yOffset;
//size of a character
int xSize;
int ySize;
//count of characters per row
int xCount;
//count of rows
int yCount;
//pixel offset of first character
int xStart;
int yStart;
unsigned int fillValue;
char firstChar;
int pixelSize;
int gap;
Font();
explicit Font(const std::string &file, const std::string &configFile);
void load(const std::string &file, const std::string &configFile);
int width();
int height();
bool getPixel(char character, int x, int y);
};
#endif //TEXTRENDERER_FONT_H

View File

@ -1,5 +1,6 @@
#include <catch2/catch.hpp> #include <catch2/catch.hpp>
#include <Bitmap.h> #include "Bitmap.h"
#include "Font.h"
TEST_CASE("default values") { TEST_CASE("default values") {
Bitmap bitmap = Bitmap(); Bitmap bitmap = Bitmap();
@ -7,3 +8,19 @@ TEST_CASE("default values") {
REQUIRE(bitmap.getHeight() == 0); REQUIRE(bitmap.getHeight() == 0);
REQUIRE(bitmap.getBitsPerPixel() == 0); REQUIRE(bitmap.getBitsPerPixel() == 0);
} }
TEST_CASE("load Bitmap") {
Bitmap bitmap = Bitmap("../res/font1.bmp");
REQUIRE(bitmap.getWidth() == 128);
REQUIRE(bitmap.getHeight() == 64);
REQUIRE(bitmap.getBitsPerPixel() == 24);
}
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(font.getPixel('a', 1,2));
}