#ifdef LV_LVGL_H_INCLUDE_SIMPLE #include "lvgl.h" #else #include "lvgl/lvgl.h" #endif #include #include #include #include "neofont.h" #define G( \ a,b,c, \ d,e,f, \ g,h,i, \ j,k,l, \ m,n,o \ ) \ { \ h + (g<<1) + (f<<2) + (e<<3) + (d << 4) + (c << 5) + (b << 6) + (a << 7), \ 0 + (o<<1) + (n<<2) + (m<<3) + (l << 4) + (k << 5) + (j << 6) + (i << 7) \ } #define X 1 #define _ 0 static uint8_t glyphs[][2] = { G( _, X, _, X, _, X, X, _, X, X, _, X, _, X, _ ), G( _, X, _, X, X, _, _, X, _, _, X, _, X, X, X ), G( _, X, _, X, _, X, _, _, X, _, X, _, X, X, X ), G( X, X, _, _, _, X, _, X, _, _, _, X, X, X, _ ), G( _, _, X, _, X, X, X, _, X, X, X, X, _, _, X ), G( X, X, X, X, _, _, X, X, _, _, _, X, X, X, _ ), G( _, X, X, X, _, _, X, X, _, X, _, X, _, X, _ ), G( X, X, X, _, _, X, _, _, X, _, X, _, _, X, _ ), G( _, X, _, X, _, X, _, X, _, X, _, X, _, X, _ ), G( _, X, _, X, _, X, _, X, X, _, _, X, X, X, _ ), G( _, X, _, X, _, X, X, _, X, X, X, X, X, _, X ), G( X, X, _, X, _, X, X, X, _, X, _, X, X, X, _ ), G( _, X, X, X, _, _, X, _, _, X, _, _, _, X, X ), G( X, X, _, X, _, X, X, _, X, X, _, X, X, X, _ ), G( X, X, X, X, _, _, X, X, _, X, _, _, X, X, X ), G( X, X, X, X, _, _, X, X, _, X, _, _, X, _, _ ), G( _, X, X, X, _, _, X, _, _, X, _, X, _, X, X ), G( X, _, X, X, _, X, X, X, X, X, _, X, X, _, X ), G( X, X, X, _, X, _, _, X, _, _, X, _, X, X, X ), G( X, X, X, _, _, X, _, _, X, X, _, X, _, X, _ ), G( X, _, X, X, _, X, X, X, _, X, _, X, X, _, X ), G( X, _, _, X, _, _, X, _, _, X, _, _, X, X, X ), G( X, _, X, X, X, X, X, _, X, X, _, X, X, _, X ), G( X, X, _, X, _, X, X, _, X, X, _, X, X, _, X ), G( X, X, X, X, _, X, X, _, X, X, _, X, X, X, X ), G( X, X, X, X, _, X, X, X, X, X, _, _, X, _, _ ), G( _, X, _, X, _, X, X, _, X, X, _, X, _, X, X ), G( X, X, _, X, _, X, X, X, _, X, _, X, X, _, X ), G( _, X, X, X, _, _, _, X, _, _, _, X, X, X, _ ), G( X, X, X, _, X, _, _, X, _, _, X, _, _, X, _ ), G( X, _, X, X, _, X, X, _, X, X, _, X, X, X, X ), G( X, _, X, X, _, X, X, _, X, _, X, _, _, X, _ ), G( X, _, X, X, _, X, X, _, X, X, X, X, X, _, X ), G( X, _, X, X, _, X, _, X, _, X, _, X, X, _, X ), G( X, _, X, X, _, X, _, X, _, _, X, _, _, X, _ ), G( X, X, X, _, _, X, _, X, _, X, _, _, X, X, X ), G( _, _, _, _, _, _, X, X, X, _, _, _, _, _, _ ), G( _, _, _, _, _, X, _, X, _, X, _, _, _, _, _ ), G( _, _, _, _, X, _, _, _, _, _, X, _, _, _, _ ), G( _, _, _, _, _, _, _, _, _, _, X, _, _, _, _ ), G( _, _, _, _, _, _, _, _, _, _, X, _, X, _, _ ), G( _, _, _, _, _, _, _, _, _, _, _, _, X, X, X ), G( X, X, _, _, _, X, _, X, _, _, _, _, _, X, _ ), G( _, X, _, _, X, _, _, X, _, _, _, _, _, X, _ ), G( X, _, _, _, _, X, _, X, _, X, _, _, _, _, X ), G( _, X, _, X, X, X, _, X, _, X, X, X, _, X, _ ), }; #undef X #undef _ #undef G /* Get info about glyph of `unicode_letter` in `font` font. * Store the result in `dsc_out`. * The next letter (`unicode_letter_next`) might be used to calculate the width required by this glyph (kerning) */ static bool neofont0_glyph_dsc_cb(const lv_font_t * font, lv_font_glyph_dsc_t * dsc_out, uint32_t unicode_letter, uint32_t unicode_letter_next) { /*Your code here*/ /* Store the result. * For example ... */ dsc_out->adv_w = 4; /*Horizontal space required by the glyph in [px]*/ dsc_out->box_h = 5; /*Height of the bitmap in [px]*/ dsc_out->box_w = 3; /*Width of the bitmap in [px]*/ dsc_out->ofs_x = 0; /*X offset of the bitmap in [pf]*/ dsc_out->ofs_y = 0; /*Y offset of the bitmap measured from the as line*/ dsc_out->bpp = 1; /*Bits per pixel: 1/2/4/8*/ return true; /*true: glyph found; false: glyph was not found*/ } /* Get the bitmap of `unicode_letter` from `font`. */ static const uint8_t * neofont0_glyph_bitmap_cb(const lv_font_t * font, uint32_t unicode_letter) { static const uint8_t spc[2] = {0,0}; /* Your code here */ // /* The bitmap should be a continuous bitstream where // * each pixel is represented by `bpp` bits */ if ('0' <= unicode_letter && unicode_letter <= '9') { return glyphs[(unicode_letter - '0')]; } if ('A' <= unicode_letter && unicode_letter <= 'Z') { return glyphs[(unicode_letter - 'A')+10]; } if ('a' <= unicode_letter && unicode_letter <= 'z') { return glyphs[(unicode_letter - 'a')+10]; } if (unicode_letter == ' ') { return spc; } static const char *symbols = "-/:.,_?!%#"; if (unicode_letter < 0x80) { char*x = strchr(symbols,((uint8_t)unicode_letter)); if (x != NULL) { return glyphs[36+(x-symbols)]; } } return glyphs[sizeof(glyphs)/sizeof(glyphs[0])-1]; } lv_font_t neofont0 = { .get_glyph_dsc = neofont0_glyph_dsc_cb, /*Set a callback to get info about gylphs*/ .get_glyph_bitmap = neofont0_glyph_bitmap_cb, /*Set a callback to get bitmap of a glyp*/ .line_height = 6, /*The real line height where any text fits*/ .base_line = 1, /*Base line measured from the top of line_height*/ .dsc = 0, /*Store any implementation specific data here*/ #if !(LVGL_VERSION_MAJOR == 6 && LVGL_VERSION_MINOR == 0) .subpx = LV_FONT_SUBPX_NONE, #endif #if LV_VERSION_CHECK(7, 4, 0) || LVGL_VERSION_MAJOR >= 8 .underline_position = 0, .underline_thickness = 0, #endif .user_data = 0 /*Optionally some extra user data*/ }; static bool neofont1_glyph_dsc_cb(const lv_font_t * font, lv_font_glyph_dsc_t * dsc_out, uint32_t unicode_letter, uint32_t unicode_letter_next) { /*Your code here*/ /* Store the result. * For example ... */ // ######..###### // ##::::..::##:: // ######..::##:: // ::::##..::##:: // ######..::##:: // ######..######.. // ######..######.. // ##::::..::##::.. // ##::::..::##::.. // ######..::##::.. // ######..::##::.. // ::::##..::##::.. // ::::##..::##::.. // ######..::##::.. // ######..::##::.. dsc_out->adv_w = 8; /*Horizontal space required by the glyph in [px]*/ dsc_out->box_h = 10; /*Height of the bitmap in [px]*/ dsc_out->box_w = 6; /*Width of the bitmap in [px]*/ dsc_out->ofs_x = 0; /*X offset of the bitmap in [pf]*/ dsc_out->ofs_y = 0; /*Y offset of the bitmap measured from the as line*/ dsc_out->bpp = 1; /*Bits per pixel: 1/2/4/8*/ return true; /*true: glyph found; false: glyph was not found*/ } #if 0 /* Get the bitmap of `unicode_letter` from `font`. */ static const uint8_t * neofont1_glyph_bitmap_cb(const lv_font_t * font, uint32_t unicode_letter) { const uint8_t *u = neofont0_glyph_bitmap_cb(font, unicode_letter); static uint8_t v[(10*10+7)/8]; uint8_t u0 = u[0]; uint8_t u1 = u[1]; // .. .. .. .. .2 .2 .1 .1 .0 .0 // .9 .8 .7 .6 .5 .4 .3 .2 .1 .0 // .. .. .. .. .2 .2 .1 .1 .0 .0 // 19 18 17 16 15 14 13 12 11 10 // .. .. .. .5 .5 .4 .4 .3 .3 .. // 29 28 27 26 25 24 23 22 21 20 // .. .. .. .5 .5 .4 .4 .3 .3 .. // 39 38 37 36 35 34 33 32 31 30 // v[7] = 0x00; uint8_t a,b,c, d,e,f, g,h,i, j,k,l, m,n,o; a = (u0>>7)&1; u0 <<= 1; b = (u0>>7)&1; u0 <<= 1; c = (u0>>7)&1; u0 <<= 1; d = (u0>>7)&1; u0 <<= 1; e = (u0>>7)&1; u0 <<= 1; f = (u0>>7)&1; u0 <<= 1; g = (u0>>7)&1; u0 <<= 1; h = (u0>>7)&1; i = (u1>>7)&1; u1 <<= 1; j = (u1>>7)&1; u1 <<= 1; k = (u1>>7)&1; u1 <<= 1; l = (u1>>7)&1; u1 <<= 1; m = (u1>>7)&1; u1 <<= 1; n = (u1>>7)&1; u1 <<= 1; o = (u1>>7)&1; #define P(a,b,c,d, e,f,g,h) ((a<<7)|(b<<6)|(c<<5)|(d<<4)|(e<<3)|(f<<2)|(g<<1)|h) v[0] = P(0,0,a,a,b,b,c,c); v[1] = P(0,0,a,a,b,b,c,c); v[2] = P(0,0,d,d,e,e,f,f); v[3] = P(0,d,d,e,e,f,f,0); v[4] = P(0,g,g,h,h,i,i,0); v[5] = P(g,g,h,h,i,i,0,0); v[6] = P(j,j,k,k,l,l,0,0); v[7] = P(j,j,k,k,l,l,0,0); v[8] = P(m,m,n,n,o,o,0,0); v[9] = P(m,m,n,n,o,o,0,0); #undef P return v; /*Or NULL if not found*/ } #endif /* Get the bitmap of `unicode_letter` from `font`. */ static const uint8_t * neofont1_glyph_bitmap_cb(const lv_font_t * font, uint32_t unicode_letter) { const uint8_t *u = neofont0_glyph_bitmap_cb(font, unicode_letter); static uint8_t v[8]; uint8_t u0 = u[0]; uint8_t u1 = u[1]; // .. .. .. .. .2 .2 .1 .1 .0 .0 // .9 .8 .7 .6 .5 .4 .3 .2 .1 .0 // .. .. .. .. .2 .2 .1 .1 .0 .0 // 19 18 17 16 15 14 13 12 11 10 // .. .. .. .5 .5 .4 .4 .3 .3 .. // 29 28 27 26 25 24 23 22 21 20 // .. .. .. .5 .5 .4 .4 .3 .3 .. // 39 38 37 36 35 34 33 32 31 30 // v[7] = 0x00; uint8_t a,b,c, d,e,f, g,h,i, j,k,l, m,n,o; a = (u0>>7)&1; u0 <<= 1; b = (u0>>7)&1; u0 <<= 1; c = (u0>>7)&1; u0 <<= 1; d = (u0>>7)&1; u0 <<= 1; e = (u0>>7)&1; u0 <<= 1; f = (u0>>7)&1; u0 <<= 1; g = (u0>>7)&1; u0 <<= 1; h = (u0>>7)&1; i = (u1>>7)&1; u1 <<= 1; j = (u1>>7)&1; u1 <<= 1; k = (u1>>7)&1; u1 <<= 1; l = (u1>>7)&1; u1 <<= 1; m = (u1>>7)&1; u1 <<= 1; n = (u1>>7)&1; u1 <<= 1; o = (u1>>7)&1; #define P(a,b,c,d, e,f,g,h) ((a<<7)|(b<<6)|(c<<5)|(d<<4)|(e<<3)|(f<<2)|(g<<1)|h) v[0] = P(a,a,b,b,c,c, a,a); v[1] = P(b,b,c,c, d,d,e,e); v[2] = P(f,f, d,d,e,e,f,f); v[3] = P(g,g,h,h,i,i, g,g); v[4] = P(h,h,i,i, j,j,k,k); v[5] = P(l,l, j,j,k,k,l,l); v[6] = P(m,m,n,n,o,o, m,m); v[7] = P(n,n,o,o, 0,0,0,0); #undef P return v; /*Or NULL if not found*/ } /*Describe the properties of a font*/ lv_font_t neofont1 = { .get_glyph_dsc = neofont1_glyph_dsc_cb, /*Set a callback to get info about gylphs*/ .get_glyph_bitmap = neofont1_glyph_bitmap_cb, /*Set a callback to get bitmap of a glyp*/ .line_height = 12, /*The real line height where any text fits*/ .base_line = 2, /*Base line measured from the top of line_height*/ .dsc = 0, /*Store any implementation specific data here*/ #if !(LVGL_VERSION_MAJOR == 6 && LVGL_VERSION_MINOR == 0) .subpx = LV_FONT_SUBPX_NONE, #endif #if LV_VERSION_CHECK(7, 4, 0) || LVGL_VERSION_MAJOR >= 8 .underline_position = 0, .underline_thickness = 0, #endif .user_data = 0 /*Optionally some extra user data*/ }; /* Get info about glyph of `unicode_letter` in `font` font. * Store the result in `dsc_out`. * The next letter (`unicode_letter_next`) might be used to calculate the width required by this glyph (kerning) */ static bool neofont2_glyph_dsc_cb(const lv_font_t * font, lv_font_glyph_dsc_t * dsc_out, uint32_t unicode_letter, uint32_t unicode_letter_next) { dsc_out->adv_w = 16; /*Horizontal space required by the glyph in [px]*/ dsc_out->box_h = 20; /*Height of the bitmap in [px]*/ dsc_out->box_w = 12; /*Width of the bitmap in [px]*/ dsc_out->ofs_x = 0; /*X offset of the bitmap in [pf]*/ dsc_out->ofs_y = 0; /*Y offset of the bitmap measured from the as line*/ dsc_out->bpp = 1; /*Bits per pixel: 1/2/4/8*/ return true; /*true: glyph found; false: glyph was not found*/ } /* Get the bitmap of `unicode_letter` from `font`. */ static const uint8_t * neofont2_glyph_bitmap_cb(const lv_font_t * font, uint32_t unicode_letter) { const uint8_t *u = neofont0_glyph_bitmap_cb(font, unicode_letter); static uint8_t v[30]; uint8_t u0 = u[0]; uint8_t u1 = u[1]; uint8_t a,b,c, d,e,f, g,h,i, j,k,l, m,n,o; a = (u0>>7)&1; u0 <<= 1; b = (u0>>7)&1; u0 <<= 1; c = (u0>>7)&1; u0 <<= 1; d = (u0>>7)&1; u0 <<= 1; e = (u0>>7)&1; u0 <<= 1; f = (u0>>7)&1; u0 <<= 1; g = (u0>>7)&1; u0 <<= 1; h = (u0>>7)&1; i = (u1>>7)&1; u1 <<= 1; j = (u1>>7)&1; u1 <<= 1; k = (u1>>7)&1; u1 <<= 1; l = (u1>>7)&1; u1 <<= 1; m = (u1>>7)&1; u1 <<= 1; n = (u1>>7)&1; u1 <<= 1; o = (u1>>7)&1; #define P(a,b) (a?0xf0:0)|(b?0x0f:0) v[0] = P(a,b); v[1] = P(c, a); v[2] = P(b,c); v[3] = v[0]; v[4] = v[1]; v[5] = v[2]; v[6] = P(d,e); v[7] = P(f, d); v[8] = P(e,f); v[9] = v[6]; v[10] = v[7]; v[11] = v[8]; v[12] = P(g,h); v[13] = P(i, g); v[14] = P(h,i); v[15] = v[12]; v[16] = v[13]; v[17] = v[14]; v[18] = P(j,k); v[19] = P(l, j); v[20] = P(k,l); v[21] = v[18]; v[22] = v[19]; v[23] = v[20]; v[24] = P(m,n); v[25] = P(o, m); v[26] = P(n,o); v[27] = v[24]; v[28] = v[25]; v[29] = v[26]; #undef P return v; /*Or NULL if not found*/ } /*Describe the properties of a font*/ lv_font_t neofont2 = { .get_glyph_dsc = neofont2_glyph_dsc_cb, /*Set a callback to get info about gylphs*/ .get_glyph_bitmap = neofont2_glyph_bitmap_cb, /*Set a callback to get bitmap of a glyp*/ .line_height = 24, /*The real line height where any text fits*/ .base_line = 4, /*Base line measured from the top of line_height*/ .dsc = 0, /*Store any implementation specific data here*/ #if !(LVGL_VERSION_MAJOR == 6 && LVGL_VERSION_MINOR == 0) .subpx = LV_FONT_SUBPX_NONE, #endif #if LV_VERSION_CHECK(7, 4, 0) || LVGL_VERSION_MAJOR >= 8 .underline_position = 0, .underline_thickness = 0, #endif .user_data = 0 /*Optionally some extra user data*/ }; /* Get info about glyph of `unicode_letter` in `font` font. * Store the result in `dsc_out`. * The next letter (`unicode_letter_next`) might be used to calculate the width required by this glyph (kerning) */ static bool neofont3_glyph_dsc_cb(const lv_font_t * font, lv_font_glyph_dsc_t * dsc_out, uint32_t unicode_letter, uint32_t unicode_letter_next) { dsc_out->adv_w = 32; /*Horizontal space required by the glyph in [px]*/ dsc_out->box_h = 40; /*Height of the bitmap in [px]*/ dsc_out->box_w = 24; /*Width of the bitmap in [px]*/ dsc_out->ofs_x = 0; /*X offset of the bitmap in [pf]*/ dsc_out->ofs_y = 0; /*Y offset of the bitmap measured from the as line*/ dsc_out->bpp = 1; /*Bits per pixel: 1/2/4/8*/ return true; /*true: glyph found; false: glyph was not found*/ } static void mono_bitmap_scale_4( const uint8_t *u, uint8_t *v, unsigned int w, unsigned int h, uint8_t *u0, uint8_t *u1, uint8_t *v0, uint8_t *v1 ) { unsigned int y = 0; uint8_t U; const uint8_t *V = v; const uint8_t *v_line_end = &(v[w]); const uint8_t *v_line_next = &(v[w<<2]); for (;;) { U = *u; if (!(v0 <= v && v < v1)) { fprintf(stderr, "Overflow 0!\n"); return; } *v = ( ((U&0x80) ? 0xf0 : 0) | ((U&0x40) ? 0x0f : 0) ); U <<= 2; v++; if (!(v0 <= v && v < v1)) { return; } *v = ( ((U&0x80) ? 0xf0 : 0) | ((U&0x40) ? 0x0f : 0) ); U <<= 2; v++; if (v >= v_line_end) { while (v < v_line_next) { if (!(v0 <= v && v < v1)) { fprintf(stderr, "Overflow 1!\n"); return; } *v = *V; v++; V++; } y++; if (y >= h) { return; } V = v; v_line_end = &(v[w]); v_line_next = &(v[w<<2]); } if (!(v0 <= v && v < v1)) { return; } *v = ( ((U&0x80) ? 0xf0 : 0) | ((U&0x40) ? 0x0f : 0) ); U <<= 2; v++; if (!(v0 <= v && v < v1)) { return; } *v = ( ((U&0x80) ? 0xf0 : 0) | ((U&0x40) ? 0x0f : 0) ); u++; v++; if (v >= v_line_end) { while (v < v_line_next) { if (!(v0 <= v && v < v1)) { fprintf(stderr, "Overflow 2!\n"); return; } *v = *V; v++; V++; } y++; if (y >= h) { return; } V = v; v_line_end = &(v[w]); v_line_next = &(v[w<<2]); } } } /* Get the bitmap of `unicode_letter` from `font`. */ static const uint8_t * neofont3_glyph_bitmap_cb(const lv_font_t * font, uint32_t unicode_letter) { const uint8_t *u = neofont1_glyph_bitmap_cb(font, unicode_letter); static uint8_t v[120 /* = 40 * 24 / 8 */ ]; mono_bitmap_scale_4(u,v,6,10,u,u+(60+7)/8,v,v+120); return v; } /*Describe the properties of a font*/ const lv_font_t neofont3 = { .get_glyph_dsc = neofont3_glyph_dsc_cb, /*Set a callback to get info about gylphs*/ .get_glyph_bitmap = neofont3_glyph_bitmap_cb, /*Set a callback to get bitmap of a glyp*/ .line_height = 48, /*The real line height where any text fits*/ .base_line = 8, /*Base line measured from the top of line_height*/ .dsc = 0, /*Store any implementation specific data here*/ #if !(LVGL_VERSION_MAJOR == 6 && LVGL_VERSION_MINOR == 0) .subpx = LV_FONT_SUBPX_NONE, #endif #if LV_VERSION_CHECK(7, 4, 0) || LVGL_VERSION_MAJOR >= 8 .underline_position = 0, .underline_thickness = 0, #endif .user_data = 0 /*Optionally some extra user data*/ };