Skip to content

Commit

Permalink
Merge branch 'gfx-font-converter' into 'master'
Browse files Browse the repository at this point in the history
Add gfx-font-converter application

See merge request embedded/general-support-library!35
  • Loading branch information
gdex committed Sep 27, 2023
2 parents faabcb9 + 92a6a85 commit 0f61f2c
Show file tree
Hide file tree
Showing 13 changed files with 627 additions and 30 deletions.
80 changes: 70 additions & 10 deletions BufferedOut.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,22 @@ char* append(char* dst, const char* end, const char* str)
namespace embedded
{

void BufferedOut::addPadding(const char* p)
{
auto realSize = p - pos;
if (realSize < integerWidth)
{
memmove(pos + integerWidth - realSize, pos, realSize);
auto paddingSize = integerWidth - realSize;
auto paddingPos = pos;
while (paddingSize-- > 0)
{
*(paddingPos++) = fillChar;
}
pos += integerWidth;
}
}

BufferedOut &BufferedOut::operator<<(const char* str)
{
pos = append(pos, dataBuf.end(), str);
Expand All @@ -49,45 +65,76 @@ BufferedOut &BufferedOut::operator<<(const char* str)
BufferedOut &BufferedOut::operator<<(int n)
{
auto [p, ec] = std::to_chars(pos, dataBuf.end(), n);
pos = p;
if (ec == std::errc {})
{
adjustPos(p);
}
return *this;
}

BufferedOut &BufferedOut::operator<<(unsigned int n)
{
auto [p, ec] = std::to_chars(pos, dataBuf.end(), n);
pos = p;
if (ec == std::errc {})
{
adjustPos(p);
}
return *this;
}

BufferedOut &BufferedOut::operator<<(long n)
{
auto [p, ec] = std::to_chars(pos, dataBuf.end(), n);
pos = p;
if (ec == std::errc {})
{
adjustPos(p);
}
return *this;
}

BufferedOut &BufferedOut::operator<<(unsigned long n)
{
auto [p, ec] = std::to_chars(pos, dataBuf.end(), n);
pos = p;
if (ec == std::errc {})
{
adjustPos(p);
}
return *this;
}

BufferedOut &BufferedOut::operator<<(long long n)
{
auto [p, ec] = std::to_chars(pos, dataBuf.end(), n);
pos = p;
if (ec == std::errc {})
{
adjustPos(p);
}
return *this;
}

BufferedOut &BufferedOut::operator<<(unsigned long long n)
{
auto [p, ec] = std::to_chars(pos, dataBuf.end(), n);
pos = p;
if (ec == std::errc {})
{
adjustPos(p);
}
return *this;
}

void BufferedOut::adjustPos(char* p)
{
if (integerWidth > 0)
{
addPadding(p);
integerWidth = 0;
}
else
{
pos = p;
}
}

BufferedOut &BufferedOut::operator<<(float f)
{
pos = toChars(pos, dataBuf.end(), f, floatPrecision);
Expand All @@ -96,16 +143,29 @@ BufferedOut &BufferedOut::operator<<(float f)

BufferedOut &BufferedOut::operator<<(ConstBytesView span)
{
char digits[] = "0123456789ABCDEF";
const size_t availableSize = (dataBuf.end() - pos) / 2;
auto size = span.size() < availableSize ? span.size() : availableSize;
for (size_t i = 0; i < size; ++i)
{
unsigned digit = span[i];
*(pos++) = digits[(digit & 0xF0u) >> 4];
*(pos++) = digits[digit & 0xFu];
*this << span[i];
}
return *this;
}

BufferedOut &BufferedOut::operator<<(unsigned char b)
{
char digits[] = "0123456789ABCDEF";
*(pos++) = digits[(b & 0xF0u) >> 4];
*(pos++) = digits[b & 0xFu];
return *this;
}

BufferedOut &BufferedOut::operator<<(std::string_view str)
{
auto effectiveSize = std::min(str.size(), static_cast<size_t>(dataBuf.end() - pos));
std::memcpy(pos, str.data(), effectiveSize);
pos += effectiveSize;
return *this;
}

} // namespace embedded
46 changes: 35 additions & 11 deletions BufferedOut.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,38 +12,55 @@ class BufferedOut
private:
MemoryView<char> dataBuf;
public:
explicit BufferedOut(MemoryView<char> dataBuf) : dataBuf(dataBuf), pos(dataBuf.begin()), floatPrecision(0) {}
explicit BufferedOut(MemoryView<char> dataBuf)
: dataBuf(dataBuf)
{
clear();
}

struct precision { int p; };
struct width { int w; };
struct fill { char f; };

BufferedOut &operator<<(const char* str);

BufferedOut &operator<<(std::string_view str);
BufferedOut &operator<<(int n);

BufferedOut &operator<<(unsigned int n);

BufferedOut &operator<<(long n);

BufferedOut &operator<<(unsigned long n);

BufferedOut &operator<<(long long n);

BufferedOut &operator<<(unsigned long long n);

BufferedOut &operator<<(float f);

BufferedOut &operator<<(unsigned char b);
BufferedOut &operator<<(ConstBytesView span);

BufferedOut &operator<<(char c)
{
addChar(c);
return *this;
}

BufferedOut &operator<<(precision p)
{
floatPrecision = p.p;
return *this;
}

BufferedOut &operator<<(width w)
{
integerWidth = w.w;
return *this;
}

BufferedOut &operator<<(fill f)
{
fillChar = f.f;
return *this;
}

BytesView data() { return { (unsigned char*)(dataBuf.begin()), static_cast<uint16_t>(size()) }; }
ConstBytesView data() const { return { (unsigned char*)(dataBuf.begin()), static_cast<uint16_t>(size()) }; }

explicit operator std::string_view() const { return { dataBuf.begin(), size() }; }
std::string_view asStringView() const { return { dataBuf.begin(), size() }; }

decltype(dataBuf)::size_type size() const { return pos - dataBuf.begin(); }
decltype(dataBuf)::size_type capacity() const { return dataBuf.size(); }
Expand All @@ -55,6 +72,8 @@ class BufferedOut
{
pos = dataBuf.begin();
floatPrecision = 0;
integerWidth = 0;
fillChar = ' ';
}

void addChar(char c)
Expand All @@ -66,8 +85,13 @@ class BufferedOut
}

private:
void addPadding(const char* p);

decltype(dataBuf)::iterator pos;
int floatPrecision;
int integerWidth;
char fillChar;
void adjustPos(char* p);
};

}
8 changes: 7 additions & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,13 @@ if ("${COMPONENT_NAME}" STREQUAL "")
target_include_directories(general-support-library PUBLIC .)
target_link_libraries(general-support-library-graphics PUBLIC general-support-library)
set_source_files_properties(graphics/EmbeddedFonts.cpp PROPERTIES COMPILE_FLAGS -Wno-missing-braces)
# Add the gtest library

find_package(Freetype)
find_package(Iconv)
if (FREETYPE_FOUND AND ICONV_FOUND)
add_subdirectory(gfx-font-converter)
endif ()

find_package(GTest)
if (GTEST_FOUND)
enable_testing()
Expand Down
54 changes: 54 additions & 0 deletions gfx-font-converter/BitStream.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
#pragma once

#include <iosfwd>
#include <cstdint>

template <typename Stream>
class BitStream
{
public:
explicit BitStream(Stream &stream) : stream(stream) {}
BitStream& operator<<(bool bit)
{
if (bit)
{
buffer |= 1 << (7 - bitCount);
}
if (++bitCount == 8)
{
stream << buffer;
buffer = 0;
bitCount = 0;
}
return *this;
}

BitStream& operator<<(uint8_t byte)
{
if (bitCount == 0)
{
stream << byte;
}
else
{
buffer |= byte >> bitCount;
stream << buffer;
buffer = byte << (8 - bitCount);
}
return *this;
}

void flush()
{
if (bitCount != 0)
{
stream << buffer;
buffer = 0;
bitCount = 0;
}
}
private:
Stream &stream;
int bitCount = 0;
uint8_t buffer = 0;
};
13 changes: 13 additions & 0 deletions gfx-font-converter/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
add_executable(gfx-font-converter
main.cpp
FontConverterConfig.cpp
EncodingConverter.cpp
)
target_link_libraries(gfx-font-converter
PRIVATE
general-support-library-graphics
Freetype::Freetype
Iconv::Iconv
)
target_compile_features(gfx-font-converter PUBLIC cxx_std_17)
target_compile_options(gfx-font-converter PRIVATE -Wall -Wextra -pedantic)
43 changes: 43 additions & 0 deletions gfx-font-converter/EncodingConverter.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
#include "EncodingConverter.h"

#include <sstream>

EncodingConverter::EncodingConverter(const char* from, const char* to) {
descriptor = iconv_open(to, from);
if (descriptor == (iconv_t) -1)
{
std::stringstream str;
if (errno == EINVAL)
{
str << "conversion from " << from <<" to " << to << " not available";
}
else
{
str << "iconv_open filed, errno is " << errno;
}

throw(std::runtime_error(str.str()));
}
}

std::string EncodingConverter::convert(char symbol) {
buf[inSize] = symbol;
size_t inBufSize = 1 + inSize;
char outBuf[4] = {};
size_t outBytesLeft = sizeof(outBuf);
char *inptr = &buf[0];
char *outptr = &outBuf[0];
if(iconv(descriptor, &inptr, &inBufSize, &outptr, &outBytesLeft) == (size_t) -1)
{
if (errno == EINVAL)
{
inSize = (inSize + 1) % 3;
}
else
{
inSize = 0;
}
return {};
}
return {outBuf, sizeof(outBuf) - outBytesLeft};
}
22 changes: 22 additions & 0 deletions gfx-font-converter/EncodingConverter.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
#pragma once

#include <iconv.h>
#include <string>

class EncodingConverter
{
public:
EncodingConverter(const char *from, const char *to);

std::string convert(char symbol);

~EncodingConverter()
{
iconv_close(descriptor);
}

private:
iconv_t descriptor;
char buf[4] = {};
size_t inSize = 0;
};
Loading

0 comments on commit 0f61f2c

Please sign in to comment.