
#ifndef FNT_H_
#define FNT_H_

#include "def.h"
#include "type.h"
#include "sys.h"

#ifndef ENABLE_FONT
#define render_str(fnt, bmem, fix, sz, x, y, str) do{}while(0)
#define load_font_to(dest) do{}while(0)
#define load_font(varn) do{}while(0)
#else
// TODO: make sz be optimized at compile-time, somehow
// TODO: however, this doesn't seem to always cause a decrease in binary size
// probably due to the immediates being larger than a shl foo, sz
static void render_str(uint8_t (*fnt)[FONTH],
    void* bmem, struct fb_fix_screeninfo fix,
    size_t sz, size_t x, size_t y, const char* str) {
//#define sz (3)
#ifndef NOFONTNL
    size_t ox = x;
#endif
    do {
#ifndef NOFONTNL
        if (*str == '\n')
        {
            x = ox;
            y += (size_t)FONTH << sz;
            goto CONTINUE;
        }
#endif

        size_t j = 0;
        do {
            size_t i = 0;
            do {
                *ADDRESS_FB(i+x, j+y) |=
#ifndef EXPAND_FONT_IN_MEM
                    GETFONTBIT(fnt[(size_t)*str], i >> sz, j >> sz) ? ~(uint32_t)0 : 0;
#else
                    fnt[(i >> sz) + (j >> sz) * FONTW + (size_t)*str * FONTH * FONTH];
#endif

                ++i;
            } while (i < (size_t)FONTW << sz);
            ++j;
        } while (j < (size_t)FONTH << sz);

        x += (size_t)8 << sz;

#ifndef NOFONTNL
CONTINUE:
#endif
        ++str;
    } while (*str);
}
//#undef sz

// TODO: add loading from KDFONTOP/GIO_FONTX

forcedinline void load_font_to(uint8_t* dest) {
#ifdef EXPAND_FONT_IN_MEM
    uint8_t fntdat[FONTFILESZ];
    SYS_read(STDIN_FILENO, fntdat, FONTFILESZ);
    const uint8_t (*pfnt)[FONTH] = fntdat;
    for (size_t c = 0; c < FONTCHARS; ++c) {
        for (size_t j = 0; j < FONTH; ++j) {
            for (size_t i = 0; i < FONTW; ++i) {
                dfnt[c * FONTH * FONTW + j * FONTW + i]
                    = GETFONTBIT(pfnt[c], i, j) ? ~(uint32_t)0 : 0;
            }
        }
    }
#else
    SYS_read(STDIN_FILENO, dest, FONTFILESZ);
#endif
}

#if !defined(EXPAND_FONT_IN_MEM)
#define load_font(varn) uint8_t __fnttmp##__LINE__[FONTFILESZ];load_font_to(__fnttmp##__LINE__);uint8_t (*varn)[FONTH]=(uint8_t(*)[FONTH])__fnttmp##__LINE__;
#else
#define load_font(varn) uint8_t varn[FONTW*FONTH*FONTCHARS];load_font_to(varn);
#endif

#endif

#endif

