[kandinsky] Introduce a KDFont class

This commit is contained in:
Romain Goyet
2018-10-06 12:49:47 +02:00
committed by LeaNumworks
parent 6221669a7e
commit da4cc4356f
4 changed files with 103 additions and 0 deletions

View File

@@ -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\

55
kandinsky/src/font.cpp Normal file
View File

@@ -0,0 +1,55 @@
#include "font.h"
#include <assert.h>
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<uint8_t *>(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);
}

View File

@@ -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;

24
kandinsky/src/palette.h Normal file
View File

@@ -0,0 +1,24 @@
#ifndef KANDINSKY_PALETTE_H
#define KANDINSKY_PALETTE_H
#include <kandinsky/color.h>
template <int S>
class KDPalette {
public:
static KDPalette Gradient(KDColor fromColor, KDColor toColor) {
KDPalette p;
for (int i=0; i<S; i++) {
p.m_colors[i] = KDColor::blend(fromColor, toColor, (0xFF*i)/S);
}
return p;
}
KDColor colorAtIndex(int i) const {
return m_colors[i];
}
private:
KDPalette() {}
KDColor m_colors[S];
};
#endif