diff --git a/SSD1306/writer.py b/SSD1306/writer.py index eb13abb..4ee6ab0 100644 --- a/SSD1306/writer.py +++ b/SSD1306/writer.py @@ -37,6 +37,7 @@ class Writer(): text_col = 0 row_clip = False # Clip or scroll when screen full col_clip = False # Clip or new line when row is full + wrap = True # Word wrap @classmethod def set_textpos(cls, row=None, col=None): @@ -47,12 +48,14 @@ class Writer(): return Writer.text_row, Writer.text_col @classmethod - def set_clip(cls, row_clip=None, col_clip=None): + def set_clip(cls, row_clip=None, col_clip=None, wrap=None): if row_clip is not None: Writer.row_clip = row_clip if col_clip is not None: Writer.col_clip = col_clip - return Writer.row_clip, Writer.col_clip + if wrap is not None: + Writer.wrap = wrap + return Writer.row_clip, Writer.col_clip, Writer.wrap def __init__(self, device, font, verbose=True): self.device = device @@ -100,8 +103,23 @@ class Writer(): def printstring(self, string, invert=False): #print('Writer.text_row = ', Writer.text_row) + # word wrapping. Assumes words separated by single space. + rstr = None + if Writer.wrap and self.stringlen(string) > self.screenwidth: + pos = 0 + lstr = string[:] + while self.stringlen(lstr) > self.screenwidth: + pos = lstr.rfind(' ') + lstr = lstr[:pos] + if pos > 0: + rstr = string[pos + 1:] + string = lstr + for char in string: self._printchar(char, invert) + if rstr is not None: + self._printchar('\n') + self.printstring(rstr, invert) # Recurse def stringlen(self, string): l = 0 @@ -172,14 +190,41 @@ class CWriter(Writer): def __init__(self,device, font, verbose=True): super().__init__(device, font, verbose) self.fgcolor = 1 + self.cpos = 0 + self.tab = 4 - def setcolor(fgcolor, bgcolor): - self.fgcolor = fgcolor - self.bgcolor = bgcolor + def setcolor(self, fgcolor=None, bgcolor=None): + if fgcolor is not None: + self.fgcolor = fgcolor + if bgcolor is not None: + self.bgcolor = bgcolor + return self.fgcolor, self.bgcolor - def _printchar(self, char, invert=False): + def tabsize(self, value=None): + if value is not None: + self.tab = value + return self.tab + + def _gchar(self, char): + if char == '\n': + self.cpos = 0 + elif char == '\t': + nspaces = self.tab - (self.cpos % self.tab) + if nspaces == 0: + nspaces = self.tab + while nspaces: + nspaces -= 1 + self._printchar(' ', recurse=True) + self.glyph = None # All done + return + super()._get_char(char) + + def _printchar(self, char, invert=False, recurse=False): #print('Writer.text_row 1 = ', Writer.text_row) - self._get_char(char) + if recurse: + self._get_char(char) + else: + self._gchar(char) #print('Writer.text_row 2 = ', Writer.text_row) if self.glyph is None: return # All done @@ -212,3 +257,4 @@ class CWriter(Writer): if drow >= self.screenheight or drow < 0: break Writer.text_col += -char_width if usd else char_width + self.cpos += 1 diff --git a/SSD1306/writer_tests.py b/SSD1306/writer_tests.py index 4b99fce..19f1e80 100644 --- a/SSD1306/writer_tests.py +++ b/SSD1306/writer_tests.py @@ -44,8 +44,9 @@ def inverse(use_spi=False, soft=True): square_side = 10 ssd.fill_rect(rhs - square_side, 0, square_side, square_side, 1) - CWriter.set_textpos(0, 0) # In case previous tests have altered it - wri = CWriter(ssd, freesans20, verbose=False) + Writer.set_textpos(0, 0) # In case previous tests have altered it + Writer.set_clip(False, False, False) # Char wrap + wri = Writer(ssd, freesans20, verbose=False) wri.printstring('Sunday\n') wri.printstring('12 Aug 2018\n') wri.printstring('10.30am', True) # Inverse text @@ -59,6 +60,7 @@ def scroll(use_spi=False, soft=True): ssd.fill_rect(rhs - square_side, 0, square_side, square_side, 1) Writer.set_textpos(0, 0) # In case previous tests have altered it + Writer.set_clip(False, False, False) # Char wrap wri = Writer(ssd, freesans20, verbose=False) wri.printstring('Sunday\n') wri.printstring('12 Aug 2018\n') @@ -77,6 +79,7 @@ def usd_scroll(use_spi=False, soft=True): # Only CWriter can do usd CWriter.invert_display() CWriter.set_textpos(HEIGHT - 1, WIDTH - 1) + CWriter.set_clip(False, False, False) # Char wrap wri = CWriter(ssd, freesans20, verbose=False) wri.printstring('Sunday\n') @@ -97,6 +100,7 @@ def usd(use_spi=False, soft=True): # Only CWriter can do usd CWriter.invert_display() CWriter.set_textpos(HEIGHT - 1, WIDTH - 1) + CWriter.set_clip(False, False, False) # Char wrap wri = CWriter(ssd, freesans20, verbose=False) wri.printstring('Sunday\n') wri.printstring('12 Aug 2018\n') @@ -107,27 +111,29 @@ def usd(use_spi=False, soft=True): def rjust(use_spi=False, soft=True): ssd = setup(use_spi, soft) # Create a display instance Writer.set_textpos(0, 0) # Previous tests may have altered it + Writer.set_clip(False, False, False) # Char wrap wri = Writer(ssd, freesans20, verbose=False) my_str = 'Sunday\n' l = wri.stringlen(my_str) - CWriter.set_textpos(col = WIDTH - l) + Writer.set_textpos(col = WIDTH - l) wri.printstring(my_str) my_str = '12 Aug 2018\n' l = wri.stringlen(my_str) - CWriter.set_textpos(col = WIDTH - l) + Writer.set_textpos(col = WIDTH - l) wri.printstring(my_str) my_str = '10.30am' l = wri.stringlen(my_str) - CWriter.set_textpos(col = WIDTH - l) + Writer.set_textpos(col = WIDTH - l) wri.printstring(my_str) ssd.show() def fonts(use_spi=False, soft=True): ssd = setup(use_spi, soft) # Create a display instance Writer.set_textpos(0, 0) # In case previous tests have altered it + Writer.set_clip(False, False, False) # Char wrap wri = Writer(ssd, freesans20, verbose=False) wri_f = Writer(ssd, fixed, verbose=False) wri_f.printstring('Sunday\n') @@ -135,17 +141,51 @@ def fonts(use_spi=False, soft=True): wri.printstring('10.30am') ssd.show() +def tabs(use_spi=False, soft=True): + ssd = setup(use_spi, soft) # Create a display instance + CWriter.set_textpos(0, 0) # In case previous tests have altered it + CWriter.set_clip(False, False, False) # Char wrap + wri = CWriter(ssd, fixed, verbose=False) + wri.printstring('1\t2\n') + wri.printstring('111\t22\n') + wri.printstring('1111\t1') + ssd.show() + +def usd_tabs(use_spi=False, soft=True): + ssd = setup(use_spi, soft) # Create a display instance + CWriter.invert_display() + CWriter.set_textpos(HEIGHT - 1, WIDTH - 1) + CWriter.set_clip(False, False, False) # Char wrap + wri = CWriter(ssd, fixed, verbose=False) + wri.printstring('1\t2\n') + wri.printstring('111\t22\n') + wri.printstring('1111\t1') + ssd.show() + CWriter.invert_display(False) # For subsequent tests + +def wrap(use_spi=False, soft=True): + ssd = setup(use_spi, soft) # Create a display instance + CWriter.set_textpos(0, 0) # In case previous tests have altered it + CWriter.set_clip(False, False, True) # Word wrap + wri = CWriter(ssd, freesans20, verbose=False) + wri.printstring('the quick brown fox jumps over') + ssd.show() + tstr = '''Test assumes a 128*64 (w*h) display. Edit WIDTH and HEIGHT in ssd1306_setup.py for others. Device pinouts are comments in ssd1306_setup.py. All tests take two boolean args: use_spi = False. Set True for SPI connected device soft=True set False to use hardware I2C/SPI. Hardware option currently fails with official SSD1306 driver. + Available tests: inverse() Show black on white text. scroll() Illustrate scrolling usd() Upside-down display. usd_scroll() Upside-down scroll test. rjust() Right justification. -fonts() Two fonts.''' +fonts() Two fonts. +tabs() Tab stops. +usd_tabs() Upside-down tabs. +wrap() Word wrapping''' print(tstr)