123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134 |
- /*
- * ui_psf2.h
- * https://gitlab.com/bztsrc/smgui
- *
- * Copyright (C) 2024 bzt (bztsrc@gitlab), MIT license
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to
- * deal in the Software without restriction, including without limitation the
- * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
- * sell copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL ANY
- * DEVELOPER OR DISTRIBUTOR BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR
- * IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- *
- * @brief Simple PSF2 font driver for SMGUI with built-in ASCII font
- */
- #ifndef UI_PSF2_H
- #define UI_PSF2_H 1
- #ifndef UI_FONT
- #define UI_FONT 1
- #else
- #error "An UI font implementation has already been included"
- #endif
- #include <stdint.h>
- #include <stdlib.h>
- #include <string.h>
- #ifndef UI_H
- #include <ui.h>
- #undef UI_H
- #endif
- #define UI_SETFONTHOOK ui_psf2_bbox,ui_psf2_draw
- #ifdef __cplusplus
- extern "C" {
- #endif
- typedef struct {
- uint32_t magic;
- uint32_t version;
- uint32_t headersize;
- uint32_t flags;
- uint32_t numglyph;
- uint32_t bytesperglyph;
- uint32_t height;
- uint32_t width;
- } ui_psf2_t;
- uint8_t ui_psf2_default[] = { 114,181,74,134,0,0,0,0,32,0,0,0,0,0,12,0,128,0,0,0,16,0,0,0,16,0,0,0,8,0,0,0,0,0,218,2,128,130,2,128,130,2,128,182,0,0,0,0,0,0,126,129,165,129,129,189,153,129,129,126,0,0,0,0,0,0,126,255,219,255,255,195,231,255,255,126,0,0,0,0,0,0,0,0,108,254,254,254,254,124,56,16,0,0,0,0,0,0,0,0,16,56,124,254,124,56,16,0,0,0,0,0,0,0,0,24,60,60,231,231,231,24,24,60,0,0,0,0,0,0,0,24,60,126,255,255,126,24,24,60,0,0,0,0,0,0,0,0,0,0,24,60,60,24,0,0,0,0,0,0,255,255,255,255,255,255,231,195,195,231,255,255,255,255,255,255,0,0,0,0,0,60,102,66,66,102,60,0,0,0,0,0,255,255,255,255,255,195,153,189,189,153,195,255,255,255,255,255,0,0,30,14,26,50,120,204,204,204,204,120,0,0,0,0,0,0,60,102,102,102,102,60,24,126,24,24,0,0,0,0,0,0,63,51,63,48,48,48,48,112,240,224,0,0,0,0,0,0,127,99,127,99,99,99,99,103,231,230,192,0,0,0,0,0,0,24,24,219,60,231,60,219,24,24,0,0,0,0,0,128,192,224,240,248,254,248,240,224,192,128,0,0,0,0,0,2,6,14,30,62,254,62,30,14,6,2,0,0,0,0,0,0,24,60,126,24,24,24,126,60,24,0,0,0,0,0,0,0,102,102,102,102,102,102,102,0,102,102,0,0,0,0,0,0,127,219,219,219,123,27,27,27,27,27,0,0,0,0,0,124,198,96,56,108,198,198,108,56,12,198,124,0,0,0,0,0,0,0,0,0,0,0,254,254,254,254,0,0,0,0,0,0,24,60,126,24,24,24,126,60,24,126,0,0,0,0,0,0,24,60,126,24,24,24,24,24,24,24,0,0,0,0,0,0,24,24,24,24,24,24,24,126,60,24,0,0,0,0,0,0,0,0,0,24,12,254,12,24,0,0,0,0,0,0,0,0,0,0,0,48,96,254,96,48,0,0,0,0,0,0,0,0,0,0,0,0,192,192,192,254,0,0,0,0,0,0,0,0,0,0,0,40,108,254,108,40,0,0,0,0,0,0,0,0,0,0,16,56,56,124,124,254,254,0,0,0,0,0,0,0,0,0,254,254,124,124,56,56,16,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,24,60,60,60,24,24,24,0,24,24,0,0,0,0,0,102,102,102,36,0,0,0,0,0,0,0,0,0,0,0,0,0,0,108,108,254,108,108,108,254,108,108,0,0,0,0,24,24,124,198,194,192,124,6,6,134,198,124,24,24,0,0,0,0,0,0,194,198,12,24,48,96,198,134,0,0,0,0,0,0,56,108,108,56,118,220,204,204,204,118,0,0,0,0,0,48,48,48,32,0,0,0,0,0,0,0,0,0,0,0,0,0,12,24,48,48,48,48,48,48,24,12,0,0,0,0,0,0,48,24,12,12,12,12,12,12,24,48,0,0,0,0,0,0,0,0,0,102,60,255,60,102,0,0,0,0,0,0,0,0,0,0,0,24,24,126,24,24,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,24,24,24,48,0,0,0,0,0,0,0,0,0,0,254,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,24,24,0,0,0,0,0,0,0,0,2,6,12,24,48,96,192,128,0,0,0,0,0,0,56,108,198,198,214,214,198,198,108,56,0,0,0,0,0,0,24,56,120,24,24,24,24,24,24,126,0,0,0,0,0,0,124,198,6,12,24,48,96,192,198,254,0,0,0,0,0,0,124,198,6,6,60,6,6,6,198,124,0,0,0,0,0,0,12,28,60,108,204,254,12,12,12,30,0,0,0,0,0,0,254,192,192,192,252,6,6,6,198,124,0,0,0,0,0,0,56,96,192,192,252,198,198,198,198,124,0,0,0,0,0,0,254,198,6,6,12,24,48,48,48,48,0,0,0,0,0,0,124,198,198,198,124,198,198,198,198,124,0,0,0,0,0,0,124,198,198,198,126,6,6,6,12,120,0,0,0,0,0,0,0,0,24,24,0,0,0,24,24,0,0,0,0,0,0,0,0,0,24,24,0,0,0,24,24,48,0,0,0,0,0,0,0,6,12,24,48,96,48,24,12,6,0,0,0,0,0,0,0,0,0,126,0,0,126,0,0,0,0,0,0,0,0,0,0,96,48,24,12,6,12,24,48,96,0,0,0,0,0,0,124,198,198,12,24,24,24,0,24,24,0,0,0,0,0,0,0,124,198,198,222,222,222,220,192,124,0,0,0,0,0,0,16,56,108,198,198,254,198,198,198,198,0,0,0,0,0,0,252,102,102,102,124,102,102,102,102,252,0,0,0,0,0,0,60,102,194,192,192,192,192,194,102,60,0,0,0,0,0,0,248,108,102,102,102,102,102,102,108,248,0,0,0,0,0,0,254,102,98,104,120,104,96,98,102,254,0,0,0,0,0,0,254,102,98,104,120,104,96,96,96,240,0,0,0,0,0,0,60,102,194,192,192,222,198,198,102,58,0,0,0,0,0,0,198,198,198,198,254,198,198,198,198,198,0,0,0,0,0,0,60,24,24,24,24,24,24,24,24,60,0,0,0,0,0,0,30,12,12,12,12,12,204,204,204,120,0,0,0,0,0,0,230,102,102,108,120,120,108,102,102,230,0,0,0,0,0,0,240,96,96,96,96,96,96,98,102,254,0,0,0,0,0,0,198,238,254,254,214,198,198,198,198,198,0,0,0,0,0,0,198,230,246,254,222,206,198,198,198,198,0,0,0,0,0,0,124,198,198,198,198,198,198,198,198,124,0,0,0,0,0,0,252,102,102,102,124,96,96,96,96,240,0,0,0,0,0,0,124,198,198,198,198,198,198,214,222,124,12,14,0,0,0,0,252,102,102,102,124,108,102,102,102,230,0,0,0,0,0,0,124,198,198,96,56,12,6,198,198,124,0,0,0,0,0,0,126,126,90,24,24,24,24,24,24,60,0,0,0,0,0,0,198,198,198,198,198,198,198,198,198,124,0,0,0,0,0,0,198,198,198,198,198,198,198,108,56,16,0,0,0,0,0,0,198,198,198,198,214,214,214,254,238,108,0,0,0,0,0,0,198,198,108,124,56,56,124,108,198,198,0,0,0,0,0,0,102,102,102,102,60,24,24,24,24,60,0,0,0,0,0,0,254,198,134,12,24,48,96,194,198,254,0,0,0,0,0,0,60,48,48,48,48,48,48,48,48,60,0,0,0,0,0,0,0,128,192,224,112,56,28,14,6,2,0,0,0,0,0,0,60,12,12,12,12,12,12,12,12,60,0,0,0,0,16,56,108,198,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,0,0,48,48,24,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,120,12,124,204,204,204,118,0,0,0,0,0,0,224,96,96,120,108,102,102,102,102,124,0,0,0,0,0,0,0,0,0,124,198,192,192,192,198,124,0,0,0,0,0,0,28,12,12,60,108,204,204,204,204,118,0,0,0,0,0,0,0,0,0,124,198,254,192,192,198,124,0,0,0,0,0,0,56,108,100,96,240,96,96,96,96,240,0,0,0,0,0,0,0,0,0,118,204,204,204,204,204,124,12,204,120,0,0,0,224,96,96,108,118,102,102,102,102,230,0,0,0,0,0,0,24,24,0,56,24,24,24,24,24,60,0,0,0,0,0,0,6,6,0,14,6,6,6,6,6,6,102,102,60,0,0,0,224,96,96,102,108,120,120,108,102,230,0,0,0,0,0,0,56,24,24,24,24,24,24,24,24,60,0,0,0,0,0,0,0,0,0,236,254,214,214,214,214,198,0,0,0,0,0,0,0,0,0,220,102,102,102,102,102,102,0,0,0,0,0,0,0,0,0,124,198,198,198,198,198,124,0,0,0,0,0,0,0,0,0,220,102,102,102,102,102,124,96,96,240,0,0,0,0,0,0,118,204,204,204,204,204,124,12,12,30,0,0,0,0,0,0,220,118,102,96,96,96,240,0,0,0,0,0,0,0,0,0,124,198,96,56,12,198,124,0,0,0,0,0,0,16,48,48,252,48,48,48,48,54,28,0,0,0,0,0,0,0,0,0,204,204,204,204,204,204,118,0,0,0,0,0,0,0,0,0,102,102,102,102,102,60,24,0,0,0,0,0,0,0,0,0,198,198,214,214,214,254,108,0,0,0,0,0,0,0,0,0,198,108,56,56,56,108,198,0,0,0,0,0,0,0,0,0,198,198,198,198,198,198,126,6,12,248,0,0,0,0,0,0,254,204,24,48,96,198,254,0,0,0,0,0,0,14,24,24,24,112,24,24,24,24,14,0,0,0,0,0,0,24,24,24,24,24,24,24,24,24,24,24,24,0,0,0,0,112,24,24,24,14,24,24,24,24,112,0,0,0,0,0,0,118,220,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,16,56,108,198,198,198,254,0,0,0,0,0 };
- /**
- * Measure string and return width, height, left margin, and baseline (top)
- */
- int ui_psf2_bbox(void *fnt, char *str, char *end, int *w, int *h, int *l, int *t)
- {
- ui_psf2_t *font = (ui_psf2_t*)fnt;
- uint32_t c;
- int mw = 0;
- if(!fnt || !str || !w || !h) return -1;
- if(h) *h = font->height;
- if(w) *w = 0;
- if(l) *l = 0;
- if(t) *t = 0;
- while(*str && (!end || str < end)) {
- if((*str & 128) != 0) {
- if(!(*str & 32)) { c = ((*str & 0x1F)<<6)|(*(str+1) & 0x3F); str += 2; } else
- if(!(*str & 16)) { c = ((*str & 0xF)<<12)|((*(str+1) & 0x3F)<<6)|(*(str+2) & 0x3F); str += 3; } else
- if(!(*str & 8)) { c = ((*str & 0x7)<<18)|((*(str+1) & 0x3F)<<12)|((*(str+2) & 0x3F)<<6)|(*(str+3) & 0x3F); str += 4; }
- else break;
- } else c = *str++;
- if(!c) break;
- switch(c) {
- case '\r': mw = 0; break;
- case '\n': mw = 0; if(h) *h += font->height; break;
- default: mw += (font->width + 1); if(w && mw > *w) *w = mw; break;
- }
- }
- return 0;
- }
- /**
- * Draw an UTF-8 string to the given pixel buffer
- */
- int ui_psf2_draw(void *fnt, char *str, char *end, uint8_t *dst, uint32_t color, int x, int y, int l, int t, int p,
- int cx0, int cy0, int cx1, int cy1)
- {
- ui_psf2_t *font = (ui_psf2_t*)fnt;
- uint32_t c, ox = x, X, Y, line, mask, offs, bpl = (font->width + 7) >> 3;
- uint8_t *glyph;
- (void)l; (void)t;
- if(!dst || !str || cx1 < 1 || cy1 < 1 || p < 4) return -1;
- if(x >= cx1 || y >= cy1) return 0;
- while(*str && (!end || str < end)) {
- if((*str & 128) != 0) {
- if(!(*str & 32)) { c = ((*str & 0x1F)<<6)|(*(str+1) & 0x3F); str += 2; } else
- if(!(*str & 16)) { c = ((*str & 0xF)<<12)|((*(str+1) & 0x3F)<<6)|(*(str+2) & 0x3F); str += 3; } else
- if(!(*str & 8)) { c = ((*str & 0x7)<<18)|((*(str+1) & 0x3F)<<12)|((*(str+2) & 0x3F)<<6)|(*(str+3) & 0x3F); str += 4; }
- else break;
- } else c = *str++;
- if(!c) break;
- switch(c) {
- case '\r': x = ox; break;
- case '\n': x = ox; y += font->height; break;
- default:
- glyph = (uint8_t*)fnt + font->headersize + (c > 0 && c < font->numglyph ? c : 0) * font->bytesperglyph;
- offs = y * p + x * 4;
- for(Y = 0; Y < font->height && y + Y < (uint32_t)cy1; Y++, glyph += bpl, offs += p)
- for(line = offs, mask = 1 << (font->width - 1), X = 0; X < font->width &&
- y + Y >= (uint32_t)cy0 && x + X < (uint32_t)cx1 && mask; X++, mask >>= 1, line += 4)
- if(x + X >= (uint32_t)cx0 && *((uint64_t*)glyph) & mask) *((uint32_t*)(dst + line)) = color;
- x += (font->width + 1);
- break;
- }
- }
- return 0;
- }
- #ifdef __cplusplus
- }
- #endif
- #endif /* UI_PSF2_H */
|