diff --git a/app/display/fonts/__init__.py b/app/display/fonts/__init__.py index d57fbd7..2f1227b 100644 --- a/app/display/fonts/__init__.py +++ b/app/display/fonts/__init__.py @@ -2,6 +2,8 @@ from .font_3x5 import font_3x5 from .font_5x7 import font_5x7 from .font_8x8 import font_8x8 from .font_16x16 import font_16x16 -from .fonts_utils import char_width -__all__ = ['font_3x5', 'font_5x7', 'font_8x8', 'font_16x16', 'char_width'] +fonts_installed = [font_3x5, font_5x7, font_8x8, font_16x16] + +__all__ = ['font_3x5', 'font_5x7', 'font_8x8', 'font_16x16', 'fonts_installed'] + diff --git a/app/display/neopixel_64x64.py b/app/display/neopixel_64x64.py index e1fa87f..76f4503 100644 --- a/app/display/neopixel_64x64.py +++ b/app/display/neopixel_64x64.py @@ -1,10 +1,10 @@ from machine import Pin # type: ignore from neopixel import NeoPixel # type: ignore -from .fonts import char_width as charwidth +from ..utils import char_width from .fonts.font_5x7 import font_5x7 from ..utils.colors import GRAY, RAINBOW, BLACK, WHITE -from ..utils.utils import ( +from ..utils.time_utils import ( get_german_timestamp_short, get_datetime_string, get_german_time_ticks, @@ -97,14 +97,14 @@ class NeoPixel_64x64(NeoPixel): if letter in self.selected_font: char_data = self.selected_font[letter] - char_width = charwidth(char_data) + charwidth = char_width(char_data) # background for the letter (full font size) [ # print(xpos, ypos) self.set_pixel(xpos, ypos, GRAY) for xpos in range( - x, x + char_width + x, x + charwidth ) # 8 because full with of character representation for ypos in range(y, y + self.font_height) ] @@ -112,10 +112,10 @@ class NeoPixel_64x64(NeoPixel): for row in range(self.font_height): row_data = char_data[row] - for col in range(char_width): + for col in range(charwidth): # Check if pixel should be lit (MSB first) # Only check bits within the actual character width - if row_data & (1 << ((char_width - 1) - col)): + if row_data & (1 << ((charwidth - 1) - col)): self.set_pixel(x + col, y + row, color) else: print(f'oops, letter does not exist in the font -> {letter}') @@ -134,8 +134,8 @@ class NeoPixel_64x64(NeoPixel): for char in text: self.draw_letter(char, current_x, y, color) # Move cursor by character width + 1 pixel spacing - char_width = charwidth(self.selected_font[char]) - current_x += char_width + 1 + charwidth = char_width(self.selected_font[char]) + current_x += charwidth + 1 def show_hello(self): """Display HELLO with timestamp""" @@ -209,10 +209,10 @@ class NeoPixel_64x64(NeoPixel): # Draw text at floating position for i, char in enumerate(text): - char_width = charwidth(self.selected_font[char]) - char_x = current_x + (i * (char_width + 1)) + charwidth = char_width(self.selected_font[char]) + char_x = current_x + (i * (charwidth + 1)) # Keep text within matrix bounds - if 0 <= char_x < self.MATRIX_WIDTH - char_width: + if 0 <= char_x < self.MATRIX_WIDTH - charwidth: self.draw_letter(char, char_x, y, color) self.write() @@ -235,7 +235,7 @@ class NeoPixel_64x64(NeoPixel): # text_width_overall = len(text) * (self.font_width + 1) ### TODO: ACHTUNG: noch zu testen !!! # Breite jedes Zeichens - text_width_overall = sum([charwidth(self.selected_font[char]) for char in text]) + text_width_overall = sum([char_width(self.selected_font[char]) for char in text]) position = 0 @@ -244,10 +244,10 @@ class NeoPixel_64x64(NeoPixel): # Draw text at current position for i, char in enumerate(text): - char_width = charwidth(self.selected_font[char]) - char_x = int(position + (i * (char_width + 1))) + charwidth = char_width(self.selected_font[char]) + char_x = int(position + (i * (charwidth + 1))) # Handle wrapping - if char_x < -char_width: + if char_x < -charwidth: char_x += self.MATRIX_WIDTH + text_width_overall if 0 <= char_x < self.MATRIX_WIDTH: self.draw_letter(char, char_x, y, color) @@ -318,6 +318,52 @@ class NeoPixel_64x64(NeoPixel): self.draw_text(text, xpos, ypos, color) # Pixel setzen self.write() # und anzeigen + def screen_text(self, text: str): + """Text für einen Screen anpassen, + Anzahl der Zeichen je Zeile begrenzen, + ebenso wird die Höhe des Screen brücksichtigt + + + Args: + text (str): Text der ausgegeben werden soll + font: Berechnungen für den Font + height (int): Pixel + width (int): Pixel + """ + + def text_per_row(txt): + pixs = 0 + visible_text = '' + for a in txt: + pixs += char_width(self.selected_font[a]) + 1 + if pixs > self.MATRIX_WIDTH: + # Zeilenende erreicht + break + visible_text += a + + return visible_text + + # Ganzzahl Division + max_visible_rows = self.MATRIX_HEIGHT // self.font_height + print(f'rows_visible: {max_visible_rows}') + + text_left = text + scn_txt = [] + for _ in range(max_visible_rows): + visible_text = text_per_row(text_left) + visible_text_len = len(visible_text) + text_left = text_left[visible_text_len:] + + scn_txt.append(visible_text) + + if not text_left: + break + + scr_txt_dict = {'visible': scn_txt, 'invisible': text_left} + + return scr_txt_dict + + # Example usage if __name__ == '__main__': diff --git a/app/tryout/__init__.py b/app/tryout/__init__.py index ba90708..cb09559 100644 --- a/app/tryout/__init__.py +++ b/app/tryout/__init__.py @@ -1,5 +1,5 @@ from .emojis import emojis_check -from .fonts import fonts_check from .weather import weather_check +from .font_checker import Font_Checker -__all__ = ['emojis_check', 'fonts_check', 'weather_check'] +__all__ = ['emojis_check', 'Font_Checker', 'weather_check'] diff --git a/app/tryout/font_checker.py b/app/tryout/font_checker.py new file mode 100644 index 0000000..f84ce51 --- /dev/null +++ b/app/tryout/font_checker.py @@ -0,0 +1,39 @@ +from app.display.neopixel_64x64 import NeoPixel_64x64 +from app.utils import align_font, colors +import app.display.fonts as fonts + +class Font_Checker(): + font = fonts.font_3x5 + + + def __init__(self, display: NeoPixel_64x64): + self.display = display + + def font_pretty(self, font): + pretty_font = align_font(font, debug=False) + print(pretty_font) + + def fonts_check(self, pretty=False) -> None: + self.display.clear() + self.display.set_font(self.font) + + height = self.display.font_height + + alphanum: str = ''.join(sorted(self.font.keys())) + + text_left = alphanum + while text_left: + # Text entsprechend des Display splitten + scr_txt_dict = self.display.screen_text(text=text_left) + print(f'scr_txt: {scr_txt_dict}') + + self.display.clear() + for idx, row_text in enumerate(scr_txt_dict['visible']): + ypos = height * idx + # display.clear_row(ypos) + self.display.write_text(row_text, 0, ypos, colors.RAINBOW[idx % 6]) + + text_left = scr_txt_dict['invisible'] + + if pretty: + self.font_pretty(self.font) diff --git a/app/tryout/fonts.py b/app/tryout/fonts.py index e962316..68bcdc6 100644 --- a/app/tryout/fonts.py +++ b/app/tryout/fonts.py @@ -1,14 +1,20 @@ -from app.display.fonts.fonts_utils import align_font, screen_text +from app.utils import align_font, colors from app.display.neopixel_64x64 import NeoPixel_64x64 -from app.utils import colors +import app.display.fonts as fonts +font = fonts.font_3x5 def font_pretty(font): pretty_font = align_font(font, debug=False) print(pretty_font) -def fonts_check(display: NeoPixel_64x64, font, pretty=False) -> None: + +def _do_fonts_check_all(display: NeoPixel_64x64, pretty=False) -> None: + pass + + +def fonts_check(display: NeoPixel_64x64, pretty=False) -> None: display.clear() display.set_font(font) @@ -19,7 +25,7 @@ def fonts_check(display: NeoPixel_64x64, font, pretty=False) -> None: text_left = alphanum while text_left: # Text entsprechend des Display splitten - scr_txt_dict = screen_text(text=text_left, display=display) + scr_txt_dict = display.screen_text(text=text_left) print(f'scr_txt: {scr_txt_dict}') display.clear() diff --git a/app/utils/__init__.py b/app/utils/__init__.py index a5ba615..46054a5 100644 --- a/app/utils/__init__.py +++ b/app/utils/__init__.py @@ -1,3 +1,5 @@ from .system_load import show_system_load from .colors import * -from .utils import * +from .time_utils import * +from .font_utils import * +from .math_utils import * \ No newline at end of file diff --git a/app/display/fonts/fonts_utils.py b/app/utils/font_utils.py similarity index 55% rename from app/display/fonts/fonts_utils.py rename to app/utils/font_utils.py index dc251da..c528772 100644 --- a/app/display/fonts/fonts_utils.py +++ b/app/utils/font_utils.py @@ -1,9 +1,4 @@ -import app.utils as utils - -# FIXME: der Import klappt nicht !!! -# from app.display.neopixel_64x64 import NeoPixel_64x64 -# from ...display.neopixel_64x64 import NeoPixel_64x64 - +from .math_utils import show_byte_matrix def char_width(char_matrix) -> int: """Berechnung der Bits für die Zeichenbreite @@ -25,7 +20,6 @@ def char_width(char_matrix) -> int: return cw - def shift_letter_right(char, letter, debug=False) -> bool: """Prüfe ob das Zeichen auch komplett nach rechts gezogen ist @@ -66,13 +60,12 @@ def shift_letter_right(char, letter, debug=False) -> bool: if debug: print('origin:') - utils.show_byte_matrix(char, letter) + show_byte_matrix(char, letter) print('shifted') - utils.show_byte_matrix(char, shifted) + show_byte_matrix(char, shifted) return shifted - def align_font(font, debug=False): chars = [char for char in font] print(chars) @@ -87,49 +80,3 @@ def align_font(font, debug=False): # return f'#keys: {len(list(font.keys()))}' return f'#keys: {len(font)}' - - -def screen_text(text: str, display: NeoPixel_64x64): - """Text für einen Screen anpassen, - Anzahl der Zeichen je Zeile begrenzen, - ebenso wird die Höhe des Screen brücksichtigt - - - Args: - text (str): Text der ausgegeben werden soll - font: Berechnungen für den Font - height (int): Pixel - width (int): Pixel - """ - - def text_per_row(txt): - pixs = 0 - visible_text = '' - for a in txt: - pixs += char_width(display.selected_font[a]) + 1 - if pixs > display.MATRIX_WIDTH: - # Zeilenende erreicht - break - visible_text += a - - return visible_text - - # Ganzzahl Division - max_visible_rows = display.MATRIX_HEIGHT // display.font_height - print(f'rows_visible: {max_visible_rows}') - - text_left = text - scn_txt = [] - for _ in range(max_visible_rows): - visible_text = text_per_row(text_left) - visible_text_len = len(visible_text) - text_left = text_left[visible_text_len:] - - scn_txt.append(visible_text) - - if not text_left: - break - - scr_txt_dict = {'visible': scn_txt, 'invisible': text_left} - - return scr_txt_dict diff --git a/app/utils/math_utils.py b/app/utils/math_utils.py new file mode 100644 index 0000000..e0e5420 --- /dev/null +++ b/app/utils/math_utils.py @@ -0,0 +1,9 @@ +def show_byte_matrix(char, matrix): + print(f'byte_matrix: char({char})') + matrix_str = [f'0x{byte:02X}' for byte in matrix] + [print(f'{matrix_str[idx]} {number_to_bitarray_msb(byte)}') for idx, byte in enumerate(matrix)] + + +def number_to_bitarray_msb(number, bits=8): + """Convert 8/16-bit number to bit array (MSB first)""" + return [(number >> i) & 1 for i in range(bits - 1, -1, -1)] diff --git a/app/utils/utils.py b/app/utils/time_utils.py similarity index 85% rename from app/utils/utils.py rename to app/utils/time_utils.py index 05f7da4..45e6631 100644 --- a/app/utils/utils.py +++ b/app/utils/time_utils.py @@ -1,17 +1,5 @@ import time - -def show_byte_matrix(char, matrix): - print(f'byte_matrix: char({char})') - matrix_str = [f'0x{byte:02X}' for byte in matrix] - [print(f'{matrix_str[idx]} {number_to_bitarray_msb(byte)}') for idx, byte in enumerate(matrix)] - - -def number_to_bitarray_msb(number, bits=8): - """Convert 8/16-bit number to bit array (MSB first)""" - return [(number >> i) & 1 for i in range(bits - 1, -1, -1)] - - def get_datetime_string(format='full'): """ Return date/time as string with different formats diff --git a/main.py b/main.py index af6c125..8d397c8 100644 --- a/main.py +++ b/main.py @@ -1,12 +1,13 @@ from app.display.neopixel_64x64 import NeoPixel_64x64 -#import app.display.fonts as fonts import app.tryout as tryout +from app.tryout.font_checker import Font_Checker # Programm Startpunkt if __name__ == '__main__': display = NeoPixel_64x64() + font_checker : Font_Checker = Font_Checker( display) + font_checker.fonts_check(pretty=False) # tryout.emojis_check(display) - # tryout.fonts_check(display, fonts.font_8x8, pretty=False) - tryout.weather_check(display, test_mode=False) + # tryout.weather_check(display, test_mode=False) # utils.show_system_load()