Initial working version of agg font rendering test
This commit is contained in:
parent
a7904eba3b
commit
f77261afa4
|
@ -27,8 +27,9 @@ struct RenFontA {
|
||||||
int height;
|
int height;
|
||||||
};
|
};
|
||||||
|
|
||||||
static void* check_alloc(void *ptr) {
|
template <typename T>
|
||||||
if (!ptr) {
|
static T* check_alloc(T *ptr) {
|
||||||
|
if (ptr == 0) {
|
||||||
fprintf(stderr, "Fatal error: memory allocation failed\n");
|
fprintf(stderr, "Fatal error: memory allocation failed\n");
|
||||||
exit(EXIT_FAILURE);
|
exit(EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
|
@ -37,9 +38,9 @@ static void* check_alloc(void *ptr) {
|
||||||
|
|
||||||
RenImage* ren_new_image(int width, int height) {
|
RenImage* ren_new_image(int width, int height) {
|
||||||
assert(width > 0 && height > 0);
|
assert(width > 0 && height > 0);
|
||||||
RenImage *image = malloc(sizeof(RenImage) + width * height * sizeof(RenColor));
|
RenImage *image = (RenImage *) malloc(sizeof(RenImage) + width * height * sizeof(RenColor));
|
||||||
check_alloc(image);
|
check_alloc(image);
|
||||||
image->pixels = (void*) (image + 1);
|
image->pixels = (RenColor*) (image + 1);
|
||||||
image->width = width;
|
image->width = width;
|
||||||
image->height = height;
|
image->height = height;
|
||||||
return image;
|
return image;
|
||||||
|
@ -50,37 +51,53 @@ void ren_free_image(RenImage *image) {
|
||||||
}
|
}
|
||||||
|
|
||||||
RenFontA* ren_load_font_agg(const char *filename, float size) {
|
RenFontA* ren_load_font_agg(const char *filename, float size) {
|
||||||
RenFont *font = NULL;
|
RenFontA *font = NULL;
|
||||||
|
|
||||||
/* init font */
|
/* init font */
|
||||||
font = check_alloc(calloc(1, sizeof(RenFontA)));
|
font = (RenFontA *) check_alloc(calloc(1, sizeof(RenFontA)));
|
||||||
font->size = size;
|
font->size = size;
|
||||||
|
|
||||||
font->renderer = new font_renderer_lcd(true, false, true, 1.8);
|
// FIXME: we should remove the gamma correction.
|
||||||
|
// So that we have just the coverage.
|
||||||
|
font->renderer = new font_renderer_lcd(true, false, false, 1.8);
|
||||||
font->renderer->load_font(filename);
|
font->renderer->load_font(filename);
|
||||||
|
|
||||||
// FIXME: figure out correct calculation for font->height with
|
// FIXME: figure out correct calculation for font->height with
|
||||||
// ascent, descent and linegap.
|
// ascent, descent and linegap.
|
||||||
fit->height = size;
|
font->height = size;
|
||||||
return font;
|
return font;
|
||||||
}
|
}
|
||||||
|
|
||||||
static GlyphSet* load_glyphset_agg(RenFont *font, int idx) {
|
static GlyphSetA* load_glyphset_agg(RenFontA *font, int idx) {
|
||||||
GlyphSet *set = check_alloc(calloc(1, sizeof(GlyphSet)));
|
const int pixel_size = 4;
|
||||||
|
GlyphSetA *set = (GlyphSetA *) check_alloc(calloc(1, sizeof(GlyphSetA)));
|
||||||
|
|
||||||
/* init image */
|
/* init image */
|
||||||
int width = 128;
|
int width = 512; // 128;
|
||||||
int height = 128;
|
int height = 512; // 128;
|
||||||
retry:
|
retry:
|
||||||
set->image = ren_new_image(width, height);
|
set->image = ren_new_image(width, height);
|
||||||
|
|
||||||
/* load glyphs */
|
memset(set->image->pixels, 0xff, width * height * pixel_size);
|
||||||
float s =
|
|
||||||
stbtt_ScaleForMappingEmToPixels(&font->stbfont, 1) /
|
agg::rendering_buffer ren_buf((agg::int8u *) set->image->pixels, width, height, -width * pixel_size);
|
||||||
stbtt_ScaleForPixelHeight(&font->stbfont, 1);
|
double x = 4, y = height - font->size * 3 / 2;
|
||||||
int res = stbtt_BakeFontBitmap(
|
int res = 0;
|
||||||
font->data, 0, font->size * s, (void*) set->image->pixels,
|
const agg::rgba8 text_color(0x00, 0x00, 0x00);
|
||||||
width, height, idx * 256, 256, set->glyphs);
|
for (int i = 0; i < 256; i++) {
|
||||||
|
if (x + font->size * 3 / 2 > width) {
|
||||||
|
x = 4;
|
||||||
|
y -= font->size * 3 / 2;
|
||||||
|
}
|
||||||
|
if (y < 0) {
|
||||||
|
res = -1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
// FIXME: we are ignoring idx and with a char we cannot pass codepoint > 255.
|
||||||
|
char text[2] = {char(i % 256), 0};
|
||||||
|
// FIXME: using font->size below is wrong.
|
||||||
|
font->renderer->render_text(ren_buf, font->size, text_color, x, y, text);
|
||||||
|
}
|
||||||
|
|
||||||
/* retry with a larger image buffer if the buffer wasn't large enough */
|
/* retry with a larger image buffer if the buffer wasn't large enough */
|
||||||
if (res < 0) {
|
if (res < 0) {
|
||||||
|
@ -90,25 +107,11 @@ retry:
|
||||||
goto retry;
|
goto retry;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* adjust glyph yoffsets and xadvance */
|
|
||||||
int ascent, descent, linegap;
|
|
||||||
stbtt_GetFontVMetrics(&font->stbfont, &ascent, &descent, &linegap);
|
|
||||||
float scale = stbtt_ScaleForMappingEmToPixels(&font->stbfont, font->size);
|
|
||||||
int scaled_ascent = ascent * scale + 0.5;
|
|
||||||
for (int i = 0; i < 256; i++) {
|
|
||||||
set->glyphs[i].yoff += scaled_ascent;
|
|
||||||
set->glyphs[i].xadvance = floor(set->glyphs[i].xadvance);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* convert 8bit data to 32bit */
|
|
||||||
for (int i = width * height - 1; i >= 0; i--) {
|
|
||||||
uint8_t n = *((uint8_t*) set->image->pixels + i);
|
|
||||||
set->image->pixels[i] = (RenColor) { .r = 255, .g = 255, .b = 255, .a = n };
|
|
||||||
}
|
|
||||||
|
|
||||||
return set;
|
return set;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
extern "C" int main(int argc, char *argv[]);
|
||||||
|
|
||||||
int main(int argc, char *argv[]) {
|
int main(int argc, char *argv[]) {
|
||||||
if (argc < 3) {
|
if (argc < 3) {
|
||||||
fprintf(stderr, "usage: %s <font-filename> <size>\n", argv[0]);
|
fprintf(stderr, "usage: %s <font-filename> <size>\n", argv[0]);
|
||||||
|
@ -116,12 +119,12 @@ int main(int argc, char *argv[]) {
|
||||||
}
|
}
|
||||||
const char *filename = argv[1];
|
const char *filename = argv[1];
|
||||||
const int size = atoi(argv[2]);
|
const int size = atoi(argv[2]);
|
||||||
RenFont *font = ren_load_font(filename, size);
|
RenFontA *font = ren_load_font_agg(filename, size);
|
||||||
GlyphSet *set = load_glyphset(font, 0);
|
GlyphSetA *set = load_glyphset_agg(font, 0);
|
||||||
SDL_Surface *surface = SDL_CreateRGBSurfaceWithFormatFrom(
|
SDL_Surface *surface = SDL_CreateRGBSurfaceWithFormatFrom(
|
||||||
set->image->pixels,
|
set->image->pixels,
|
||||||
set->image->width, set->image->height, 32, set->image->width * 4,
|
set->image->width, set->image->height, 32, set->image->width * 4,
|
||||||
SDL_PIXELFORMAT_RGBA32);
|
SDL_PIXELFORMAT_RGBA32);
|
||||||
SDL_SaveBMP(surface, "stb-glyphset.bmp");
|
SDL_SaveBMP(surface, "agg-glyphset.bmp");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,18 +1,13 @@
|
||||||
lite_sources = [
|
|
||||||
'api/api.c',
|
|
||||||
'api/renderer.c',
|
|
||||||
'api/renderer_font.c',
|
|
||||||
'api/system.c',
|
|
||||||
'renderer.c',
|
|
||||||
'agg_font_freetype.cpp',
|
|
||||||
'font_render_capi.cpp',
|
|
||||||
'rencache.c',
|
|
||||||
'main.c',
|
|
||||||
]
|
|
||||||
|
|
||||||
executable('stb-font-render-test',
|
executable('stb-font-render-test',
|
||||||
'stb_font_render_test.c',
|
'stb_font_render_test.c',
|
||||||
include_directories: lite_include,
|
include_directories: lite_include,
|
||||||
dependencies: [sdl_dep, stb_truetype_dep, libm, libdl],
|
dependencies: [sdl_dep, stb_truetype_dep, libm, libdl],
|
||||||
install: false,
|
install: false,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
executable('agg-font-render-test',
|
||||||
|
['agg_font_render_test.cpp', '../src/agg_font_freetype.cpp'],
|
||||||
|
include_directories: lite_include,
|
||||||
|
dependencies: [sdl_dep, libagg_dep, freetype_dep, libm, libdl],
|
||||||
|
install: false,
|
||||||
|
)
|
||||||
|
|
Loading…
Reference in New Issue