From 824e603b236b7fd8302b3a6ca65ad05c1afa7fbc Mon Sep 17 00:00:00 2001 From: Clyne Sullivan Date: Sun, 5 Jun 2022 18:40:17 -0400 Subject: [PATCH] switch to bit-font for text --- source/bit-font2.c | 141 +++++++++++++++++++++++++++++++++++++ source/bit-font2.h | 43 ++++++++++++ source/dogs.c | 170 +++++++++++++++------------------------------ 3 files changed, 240 insertions(+), 114 deletions(-) create mode 100644 source/bit-font2.c create mode 100644 source/bit-font2.h diff --git a/source/bit-font2.c b/source/bit-font2.c new file mode 100644 index 0000000..91c001b --- /dev/null +++ b/source/bit-font2.c @@ -0,0 +1,141 @@ +/* + Copyright 2022 Bga + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + http://www.apache.org/licenses/LICENSE-2.0 + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + + Modified by tcsullivan: + - compacted code to only what is required + - changed ordering of font bitmap data for easier rendering + - added functional interface +*/ + +#include + +#define MAKE_GLYPH(hi, lo) (((hi * 3) << 8) | lo * 3) + +const uint8_t halfGlyphData[] = { + 0x00, 0x00, 0x00, + 0x0C, 0x03, 0x00, + 0x0C, 0xC3, 0x30, + 0xF3, 0x3C, 0xCF, + 0xFF, 0x3C, 0xCF, + 0xF3, 0x3C, 0xFF, + 0xFF, 0x3C, 0xFF, + 0x3F, 0x0C, 0xFF, + 0xFF, 0x30, 0xFC, + 0xCF, 0x30, 0xFC, + 0xC3, 0x30, 0xFC, + 0x3F, 0x0C, 0xC3, + 0xFF, 0x30, 0x0C, + 0x0C, 0xC3, 0xFC, + 0xFF, 0x3F, 0x87, + 0xE1, 0xFC, 0xFF, + 0xF3, 0xEC, 0x31, + 0xCC, 0x3F, 0xCF, + 0xF3, 0x6C, 0xF3, + 0xBC, 0x3D, 0xCF, + 0x37, 0x0C, 0xFF, + 0xFE, 0x3C, 0xFB, + 0x30, 0x0C, 0xC3, + 0x30, 0x3C, 0xFF, +}; + +const uint16_t glyphData[] = { + /* d0 */ MAKE_GLYPH(5, 4), + /* d1 */ MAKE_GLYPH(2, 2), + /* d2 */ MAKE_GLYPH(8, 11), + /* d3 */ MAKE_GLYPH(9, 12), + /* d4 */ MAKE_GLYPH(4, 10), + /* d5 */ MAKE_GLYPH(7, 8), + /* d6 */ MAKE_GLYPH(7, 4), + /* d7 */ MAKE_GLYPH(9, 2), + /* d8 */ MAKE_GLYPH(6, 4), + /* d9 */ MAKE_GLYPH(6, 12), + /* space */ MAKE_GLYPH(0, 0), + /* dot */ MAKE_GLYPH(0, 1), + /* comma */ MAKE_GLYPH(0, 2), + /* colon */ MAKE_GLYPH(1, 1), + /* asterick */ MAKE_GLYPH(2, 1), + /* questionMark */ MAKE_GLYPH(9, 1), + /* quote */ MAKE_GLYPH(2, 0), + /* doubleQuote */ MAKE_GLYPH(3, 0), + /* lowTriangle */ MAKE_GLYPH(1, 4), + /* A */ MAKE_GLYPH(6, 3), + /* B */ MAKE_GLYPH(21, 21), + /* C */ MAKE_GLYPH(23, 4), + /* D */ MAKE_GLYPH(18, 19), + /* E */ MAKE_GLYPH(7, 7), + /* F */ MAKE_GLYPH(7, 22), + /* G */ MAKE_GLYPH(20, 4), + /* H */ MAKE_GLYPH(4, 3), + /* I */ MAKE_GLYPH(2, 2), + /* J */ MAKE_GLYPH(10, 4), + /* K */ MAKE_GLYPH(19, 18), + /* L */ MAKE_GLYPH(22, 11), + /* M */ MAKE_GLYPH(14, 3), + /* N */ MAKE_GLYPH(18, 3), + /* O */ MAKE_GLYPH(5, 4), + /* P */ MAKE_GLYPH(6, 22), + /* Q */ MAKE_GLYPH(5, 17), + /* R */ MAKE_GLYPH(6, 18), + /* S */ MAKE_GLYPH(7, 8), + /* T */ MAKE_GLYPH(13, 2), + /* U */ MAKE_GLYPH(3, 4), + /* V */ MAKE_GLYPH(3, 19), + /* W */ MAKE_GLYPH(3, 15), + /* X */ MAKE_GLYPH(17, 16), + /* Y */ MAKE_GLYPH(4, 2), + /* Z */ MAKE_GLYPH(9, 11), + /* caret */ MAKE_GLYPH(16, 0), + /* squareBracketOpen */ MAKE_GLYPH(23, 17), + /* squareBracketClose */ MAKE_GLYPH(10, 12) +}; + +const char glyphKeys[47] = { + '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', + ' ', + '.', + ',', + ':', + '!', + '?', + '\'', + '"', + 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', + '^', + '[', + ']' +}; + +const uint8_t *bitfontGetBitmapLo(unsigned int gindex) +{ + if (gindex < sizeof(glyphKeys)) + return halfGlyphData + (glyphData[gindex] & 0x00FF); + else + return 0; +} + +const uint8_t *bitfontGetBitmapHi(unsigned int gindex) +{ + if (gindex < sizeof(glyphKeys)) + return halfGlyphData + ((glyphData[gindex] >> 8) & 0xFF); + else + return 0; +} + +unsigned int bitfontGetGlyph(char c) +{ + for (unsigned int i = 0; i < sizeof(glyphKeys); ++i) { + if (glyphKeys[i] == c) + return i; + } + + return 15; // Glyph for '?' +} diff --git a/source/bit-font2.h b/source/bit-font2.h new file mode 100644 index 0000000..626a20c --- /dev/null +++ b/source/bit-font2.h @@ -0,0 +1,43 @@ +/* + Copyright 2022 Bga + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + http://www.apache.org/licenses/LICENSE-2.0 + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + + Modified by tcsullivan: + - compacted code to only what is required + - changed ordering of font bitmap data for easier rendering + - added functional interface +*/ + +#ifndef BIT_FONT2_H +#define BIT_FONT2_H + +#include + +/** + * Looks up the glyph number for the given character. + * Returns glyph for '?' if character is not supported. + */ +unsigned int bitfontGetGlyph(char c); + +/** + * Returns bitmap for "hi" portion of given glyph. + * Returns NULL if glyph index is too large. + */ +const uint8_t *bitfontGetBitmapHi(unsigned int gindex); + +/** + * Returns bitmap for "lo" portion of given glyph. + * Returns NULL if glyph index is too large. + */ +const uint8_t *bitfontGetBitmapLo(unsigned int gindex); + +#endif // BIT_FONT2_H + diff --git a/source/dogs.c b/source/dogs.c index b986845..ab0b20d 100644 --- a/source/dogs.c +++ b/source/dogs.c @@ -9,6 +9,7 @@ * See the GNU General Public License for more details. */ +#include "bit-font2.h" //#include "ch.h" #include "dogs.h" #include "hal.h" @@ -215,142 +216,83 @@ void draw_rect(int x, int y, int w, int h) } } -void draw_bitmap(int x, int y, const unsigned char *buffer) +void draw_bitmap_wh(int x, int y, int w, int h, const unsigned char *data) { - // Prepare source information - const unsigned char *src = buffer; - const int width = *src++; - const int height = *src++; int sbit = 0; - for (int j = 0; j < height; j++) { - for (int i = 0; i < width; i++) { - draw_pixel(x + i, y + j, *src & (1 << sbit)); + for (int j = 0; j < h; j++) { + for (int i = 0; i < w; i++) { + draw_pixel(x + i, y + j, *data & (1 << sbit)); if (++sbit == 8) { sbit = 0; - ++src; + ++data; } } } } -static const unsigned char draw_number_bitmaps[10][10] = { - { 8, 8, // '0' - 0b00011000, - 0b00100100, - 0b01000010, - 0b01000010, - 0b01000010, - 0b01000010, - 0b00100100, - 0b00011000, - }, - { 8, 8, // '1' - 0b01111100, - 0b00010000, - 0b00010000, - 0b00010000, - 0b00010000, - 0b00010000, - 0b00010100, - 0b00011000, - }, - { 8, 8, // '2' - 0b01111110, - 0b00001000, - 0b00010000, - 0b00100000, - 0b01000000, - 0b01000010, - 0b00100100, - 0b00011000, - }, - { 8, 8, // '3' - 0b00011100, - 0b00100010, - 0b01000000, - 0b00100000, - 0b00111100, - 0b01000000, - 0b00100010, - 0b00011100, - }, - { 8, 8, // '4' - 0b00100000, - 0b00100000, - 0b00100000, - 0b00111110, - 0b00100100, - 0b00101000, - 0b00110000, - 0b00100000, - }, - { 8, 8, // '5' - 0b00011100, - 0b00100010, - 0b01000000, - 0b01000000, - 0b00100000, - 0b00011110, - 0b00000010, - 0b01111110, - }, - { 8, 8, // '6' - 0b00011000, - 0b00100100, - 0b01000010, - 0b01000110, - 0b00111010, - 0b00000010, - 0b00000100, - 0b00111000, - }, - { 8, 8, // '7' - 0b00001000, - 0b00001000, - 0b00001000, - 0b00001000, - 0b00010000, - 0b00100000, - 0b01000000, - 0b01111110, - }, - { 8, 8, // '8' - 0b00011000, - 0b00100100, - 0b01000010, - 0b00100100, - 0b00111100, - 0b01000010, - 0b00100100, - 0b00011000, - }, - { 8, 8, // '9' - 0b00011100, - 0b00100010, - 0b01000000, - 0b01111000, - 0b01000100, - 0b01000010, - 0b00100100, - 0b00011000, - }, -}; +void draw_bitmap(int x, int y, const unsigned char *buffer) +{ + draw_bitmap_wh(x, y, buffer[0], buffer[1], buffer + 2); +} + +void draw_glyph(int ix, int iy, unsigned int glyph) +{ + const unsigned char *ptr; + int x, y, sbit, tbits; + + x = ix + 5; + y = iy; + ptr = bitfontGetBitmapLo(glyph); + sbit = 0; + tbits = 18; + +draw_glyph_loop: + for (int i = 0; i < tbits; ++i) { + draw_pixel(x, y, *ptr & (1 << sbit)); + + if (x == ix) { + x += 5; + ++y; + } else { + --x; + } + + if (sbit == 7) { + sbit = 0; + ++ptr; + } else { + ++sbit; + } + } + + if (tbits == 18) { + ptr = bitfontGetBitmapHi(glyph); + sbit = 0; + tbits = 24; + goto draw_glyph_loop; + } +} void draw_number(int x, int y, int number) { + // TODO Handle negatives better? if (number < 0) number = -number; + + // Count digits int tmp = number; int count; for (count = 0; tmp; count++) tmp /= 10; if (count == 0) count = 1; - x += count * 8; + + // Draw digits + x += count * 7; do { - x -= 8; - draw_bitmap(x, y, draw_number_bitmaps[number % 10]); + x -= 7; + draw_glyph(x, y, bitfontGetGlyph('0' + (number % 10))); } while (number /= 10); }