From da4cc4356f53becdd5681feddfad49e7df741472 Mon Sep 17 00:00:00 2001 From: Romain Goyet Date: Sat, 6 Oct 2018 12:49:47 +0200 Subject: [PATCH] [kandinsky] Introduce a KDFont class --- kandinsky/Makefile | 2 ++ kandinsky/src/font.cpp | 55 ++++++++++++++++++++++++++++++++++++ kandinsky/src/font_small.cpp | 22 +++++++++++++++ kandinsky/src/palette.h | 24 ++++++++++++++++ 4 files changed, 103 insertions(+) create mode 100644 kandinsky/src/font.cpp create mode 100644 kandinsky/src/font_small.cpp create mode 100644 kandinsky/src/palette.h diff --git a/kandinsky/Makefile b/kandinsky/Makefile index 95d46eab1..a31db5019 100644 --- a/kandinsky/Makefile +++ b/kandinsky/Makefile @@ -6,6 +6,8 @@ objs += $(addprefix kandinsky/src/,\ context_pixel.o\ context_rect.o\ context_text.o\ + font.o\ + font_small.o\ framebuffer.o\ framebuffer_context.o\ ion_context.o\ diff --git a/kandinsky/src/font.cpp b/kandinsky/src/font.cpp new file mode 100644 index 000000000..f2b284b4e --- /dev/null +++ b/kandinsky/src/font.cpp @@ -0,0 +1,55 @@ +#include "font.h" +#include + +void decompress(const uint8_t * source, int sourceLength, uint8_t * output, int outputLength); + +void KDFont::fetchGreyscaleGlyphForChar(char c, uint8_t * greyscaleBuffer) const { + decompress( + compressedGlyphData(c), + compressedGlyphDataSize(c), + greyscaleBuffer, + m_glyphWidth*m_glyphHeight + ); +} + +void KDFont::fetchGlyphForChar(char c, const KDFont::RenderPalette & renderPalette, KDColor * pixelBuffer) const { + /* Since a greyscale value is smaller than a color value (see assertion), we + * can store the temporary greyscale values in the output pixel buffer. + * What's great is that now, if we fill the pixel buffer right-to-left with + * colors derived from the temporary greyscale values, we will never overwrite + * the remaining grayscale values since those are smaller. So we can avoid a + * separate buffer for the temporary greyscale values. */ + assert(k_bitsPerPixel < 8*sizeof(KDColor)); + uint8_t * greyscaleBuffer = reinterpret_cast(pixelBuffer); + fetchGreyscaleGlyphForChar(c, greyscaleBuffer); + + int numberOfPixels = m_glyphWidth*m_glyphHeight; + uint8_t mask = (0xFF >> (8-k_bitsPerPixel)); + int pixelIndex = m_glyphWidth * m_glyphHeight; + int greyscaleByteIndex = pixelIndex / k_bitsPerPixel; + while (pixelIndex >= 0) { + uint8_t greyscaleByte = greyscaleBuffer[greyscaleByteIndex--]; + assert(greyscaleByteIndex >= 0); + for (int j=0; j<8/k_bitsPerPixel; j++) { + uint8_t greyscale = greyscaleByte & mask; + greyscaleByte = greyscaleByte >> k_bitsPerPixel; + pixelBuffer[pixelIndex--] = renderPalette.colorAtIndex(greyscale); + } + } +} + +constexpr int glyphPixelCount = 12; + +void drawString(const char * text, KDColor textColor, KDColor backgroundColor) { + const KDFont * font = KDFont::LargeFont; + KDFont::RenderPalette palette = font->renderPalette(textColor, backgroundColor); + + assert(glyphPixelCount >= font->glyphWidth() * font->glyphHeight()); + + char c; + do { + char c = text[0]; + KDColor glyph[glyphPixelCount]; + font->fetchGlyphForChar(c, palette, glyph); + } while (c != 0); +} diff --git a/kandinsky/src/font_small.cpp b/kandinsky/src/font_small.cpp new file mode 100644 index 000000000..d48655e43 --- /dev/null +++ b/kandinsky/src/font_small.cpp @@ -0,0 +1,22 @@ +#include "font.h" + +static constexpr KDCoordinate glyphWidth = 8; + +static constexpr KDCoordinate glyphHeight = 8; + +static constexpr uint16_t glyphDataOffset[] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +}; + +static constexpr uint8_t glyphData[] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00 +}; + +constexpr KDFont font(glyphWidth, glyphHeight, glyphDataOffset, glyphData); + +const KDFont * KDFont::SmallFont = &font; diff --git a/kandinsky/src/palette.h b/kandinsky/src/palette.h new file mode 100644 index 000000000..98164ad22 --- /dev/null +++ b/kandinsky/src/palette.h @@ -0,0 +1,24 @@ +#ifndef KANDINSKY_PALETTE_H +#define KANDINSKY_PALETTE_H + +#include + +template +class KDPalette { +public: + static KDPalette Gradient(KDColor fromColor, KDColor toColor) { + KDPalette p; + for (int i=0; i