From 206bff6f9ae3ccbcb48830ea119bae21faa6e7d0 Mon Sep 17 00:00:00 2001 From: "Paulus H.J. Schulinck" Date: Thu, 12 May 2022 12:47:03 +0100 Subject: [PATCH 01/18] Taken out 4 of 5 examples According suggestions of @FoamyGuy, I took out 4 out of the 5 examples I created. I also took out the /images/bgimg4.bmp. This all for the sake of being able to publish a PR in a next step. --- .gitignore | 1 + examples/bmps/active_tab_sprite.bmp | Bin 0 -> 1730 bytes examples/bmps/active_tab_sprite.bmp.license | 2 + examples/bmps/inactive_tab_sprite.bmp | Bin 0 -> 1738 bytes examples/bmps/inactive_tab_sprite.bmp.license | 2 + ...layout_hotplug_ext_rtc_temp_sensor_test.py | 513 ++++++++++++++++++ .../images/BGimage4.license | 3 + examples/secrets.py | 14 + 8 files changed, 535 insertions(+) create mode 100644 examples/bmps/active_tab_sprite.bmp create mode 100644 examples/bmps/active_tab_sprite.bmp.license create mode 100644 examples/bmps/inactive_tab_sprite.bmp create mode 100644 examples/bmps/inactive_tab_sprite.bmp.license create mode 100644 examples/hotplug_sensor_examples/displayio_layout_tab_layout_hotplug_ext_rtc_temp_sensor_test.py create mode 100644 examples/hotplug_sensor_examples/images/BGimage4.license create mode 100644 examples/secrets.py diff --git a/.gitignore b/.gitignore index 544ec4a..5247efd 100644 --- a/.gitignore +++ b/.gitignore @@ -45,3 +45,4 @@ _build .idea .vscode *~ +examples/hotplug_sensor_examples/images/BGimage4.bmp diff --git a/examples/bmps/active_tab_sprite.bmp b/examples/bmps/active_tab_sprite.bmp new file mode 100644 index 0000000000000000000000000000000000000000..d97d1db459fca77099770dbe32072eeca6e7a2fd GIT binary patch literal 1730 zcmZ?rJ;cTU28V!T4G`M^u>lY>GOz$iAOOlM>p?IdkPE^L4F6#W%yV)NDh4x1Aehk9 z{s)@*pAl#-5CrABFa#AkGX#}7G6Xl+Fod*PFoaFjVF;hC!VtNNfgxgv7(?tzNrs9= z5e%yqDd7ZKK((XtIDlY>GOz$iAOOlM>p`#pkPE^L4F6#W%yV)NDh4x1Aehk9 z{s)@*pYcC~zrR0&e}ErDK&&@IP`(R8P@ywJP^lwBaDxp)NUH@y*i;>c@YyO1k*gRO zB9@3T#IBTNs8|%iaORK_PM~v!fw25xoZ6MZ`UhH`QvXq?{|&AEPoeuLj{i~nm2d%~ z^3PBYzazMOucYJyDnE|mmX86-|2c_Ue$IIY2ACveI4faQ747GYPQeg|Yc&;d8F%lCq<2U>7u88!u3XTZjT3^=nh1YL#e>@!g9 fU 999: + cnt = 0 + # change page by next page function. It will loop by default + time.sleep(2) + test_page_layout.next_page() + except KeyboardInterrupt as exc: + raise KeyboardInterrupt("Keyboard interrupt...exiting...") from exc + # raise SystemExit + + +if __name__ == "__main__": + + main() diff --git a/examples/hotplug_sensor_examples/images/BGimage4.license b/examples/hotplug_sensor_examples/images/BGimage4.license new file mode 100644 index 0000000..0d48d75 --- /dev/null +++ b/examples/hotplug_sensor_examples/images/BGimage4.license @@ -0,0 +1,3 @@ +# SPDX-FileCopyrightText: 2022 PaulskPt +# +# SPDX-License-Identifier: MIT diff --git a/examples/secrets.py b/examples/secrets.py new file mode 100644 index 0000000..e05bd25 --- /dev/null +++ b/examples/secrets.py @@ -0,0 +1,14 @@ +# SPDX-FileCopyrightText: 2022 PaulskPt +# +# SPDX-License-Identifier: MIT +# +# This file is where you keep secret settings, passwords, and tokens! +# If you put them in the code you risk committing that info or sharing it + +secrets = { + "ssid": "here your WiFi SSID", + "password": "here your WiFi password", + "aio_username": "here your aio username", + "aio_key": "here your aio key", + "timezone": "Europe/Lisbon", # http://worldtimeapi.org/timezones +} From 977c6fa62bd395cf4124d99540cd21120033b82d Mon Sep 17 00:00:00 2001 From: "Paulus H.J. Schulinck" Date: Thu, 12 May 2022 14:21:24 +0100 Subject: [PATCH 02/18] mod example --- ..._layout_tab_layout_hotplug_ext_rtc_temp_sensor_test.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/examples/hotplug_sensor_examples/displayio_layout_tab_layout_hotplug_ext_rtc_temp_sensor_test.py b/examples/hotplug_sensor_examples/displayio_layout_tab_layout_hotplug_ext_rtc_temp_sensor_test.py index d99d5ab..f4c3ea1 100644 --- a/examples/hotplug_sensor_examples/displayio_layout_tab_layout_hotplug_ext_rtc_temp_sensor_test.py +++ b/examples/hotplug_sensor_examples/displayio_layout_tab_layout_hotplug_ext_rtc_temp_sensor_test.py @@ -109,12 +109,12 @@ display=board.DISPLAY, tab_text_scale=2, custom_font=font, - inactive_tab_spritesheet="lib/adafruit_displayio_layout/examples/bmps/inactive_tab_sprite.bmp", - showing_tab_spritesheet="lib/adafruit_displayio_layout/examples/bmps/active_tab_sprite.bmp", - active_tab_text_color=0x00AA59, + inactive_tab_spritesheet="bmps/inactive_tab_sprite.bmp", + showing_tab_spritesheet="bmps/active_tab_sprite.bmp", + showing_tab_text_color=0x00AA59, inactive_tab_text_color=0xEEEEEE, inactive_tab_transparent_indexes=(0, 1), - active_tab_transparent_indexes=(0, 1), + showing_tab_transparent_indexes=(0, 1), tab_count=4, ) From 447425758b4fb7678cf77e26bb6d5f4a64ecb983 Mon Sep 17 00:00:00 2001 From: "Paulus H.J. Schulinck" Date: Thu, 12 May 2022 15:10:24 +0100 Subject: [PATCH 03/18] mod in test mod dict pages to use different Tab texts when using a PyPortal model Titano --- ...yio_layout_tab_layout_hotplug_ext_rtc_temp_sensor_test.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/examples/hotplug_sensor_examples/displayio_layout_tab_layout_hotplug_ext_rtc_temp_sensor_test.py b/examples/hotplug_sensor_examples/displayio_layout_tab_layout_hotplug_ext_rtc_temp_sensor_test.py index f4c3ea1..35f1166 100644 --- a/examples/hotplug_sensor_examples/displayio_layout_tab_layout_hotplug_ext_rtc_temp_sensor_test.py +++ b/examples/hotplug_sensor_examples/displayio_layout_tab_layout_hotplug_ext_rtc_temp_sensor_test.py @@ -212,7 +212,10 @@ pge4_group.append(pge4_lbl3) pge4_group.append(rectangle) -pages = {0: "One", 1: "Two", 2: "Thr", 3: "For"} +if board.board_id == "pyportal_titano": + pages = {0: "Dum", 1: "One", 2: "Two", 3: "Three", 4: "Four"} +else: + pages = {0: "Dum", 1: "One", 2: "Two", 3: "Thr", 3: "For"} # add the pages to the layout, supply your own page names test_page_layout.add_content(pge1_group, pages[0]) From 3beeb82933c631efd4407fab2d550e832b7d3882 Mon Sep 17 00:00:00 2001 From: "Paulus H.J. Schulinck" Date: Thu, 12 May 2022 15:26:19 +0100 Subject: [PATCH 04/18] mod example Index to dictionary pages has to start at 1, not at 0 (which is a 'dummy) --- ..._layout_tab_layout_hotplug_ext_rtc_temp_sensor_test.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/examples/hotplug_sensor_examples/displayio_layout_tab_layout_hotplug_ext_rtc_temp_sensor_test.py b/examples/hotplug_sensor_examples/displayio_layout_tab_layout_hotplug_ext_rtc_temp_sensor_test.py index 35f1166..4aae37c 100644 --- a/examples/hotplug_sensor_examples/displayio_layout_tab_layout_hotplug_ext_rtc_temp_sensor_test.py +++ b/examples/hotplug_sensor_examples/displayio_layout_tab_layout_hotplug_ext_rtc_temp_sensor_test.py @@ -218,10 +218,10 @@ pages = {0: "Dum", 1: "One", 2: "Two", 3: "Thr", 3: "For"} # add the pages to the layout, supply your own page names -test_page_layout.add_content(pge1_group, pages[0]) -test_page_layout.add_content(pge2_group, pages[1]) -test_page_layout.add_content(pge3_group, pages[2]) -test_page_layout.add_content(pge4_group, pages[3]) +test_page_layout.add_content(pge1_group, pages[1]) +test_page_layout.add_content(pge2_group, pages[2]) +test_page_layout.add_content(pge3_group, pages[3]) +test_page_layout.add_content(pge4_group, pages[4]) # test_page_layout.add_content(displayio.Group(), "page_5") From d354d357c410a37cc43098313c5e5c5e5c22b1c2 Mon Sep 17 00:00:00 2001 From: "Paulus H.J. Schulinck" Date: Thu, 12 May 2022 18:36:04 +0100 Subject: [PATCH 05/18] example default datetime setting modified idem --- ...playio_layout_tab_layout_hotplug_ext_rtc_temp_sensor_test.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/hotplug_sensor_examples/displayio_layout_tab_layout_hotplug_ext_rtc_temp_sensor_test.py b/examples/hotplug_sensor_examples/displayio_layout_tab_layout_hotplug_ext_rtc_temp_sensor_test.py index 4aae37c..40be9e0 100644 --- a/examples/hotplug_sensor_examples/displayio_layout_tab_layout_hotplug_ext_rtc_temp_sensor_test.py +++ b/examples/hotplug_sensor_examples/displayio_layout_tab_layout_hotplug_ext_rtc_temp_sensor_test.py @@ -20,7 +20,7 @@ from adafruit_displayio_layout.layouts.tab_layout import TabLayout # Adjust here the date and time that you want the RTC to be set at start: -default_dt = time.struct_time((2022, 5, 2, 2, 48, 0, 0, -1, -1)) +default_dt = time.struct_time((2022, 5, 12, 18, 34, 0, 3, -1, -1)) my_debug = True From 8d1c916ef4b258cd5f63e0228d0f4f823e9f90be Mon Sep 17 00:00:00 2001 From: "Paulus H.J. Schulinck" Date: Thu, 12 May 2022 18:48:46 +0100 Subject: [PATCH 06/18] removed images subfolder idem --- examples/hotplug_sensor_examples/images/BGimage4.license | 3 --- 1 file changed, 3 deletions(-) delete mode 100644 examples/hotplug_sensor_examples/images/BGimage4.license diff --git a/examples/hotplug_sensor_examples/images/BGimage4.license b/examples/hotplug_sensor_examples/images/BGimage4.license deleted file mode 100644 index 0d48d75..0000000 --- a/examples/hotplug_sensor_examples/images/BGimage4.license +++ /dev/null @@ -1,3 +0,0 @@ -# SPDX-FileCopyrightText: 2022 PaulskPt -# -# SPDX-License-Identifier: MIT From ace51c787388d52c65b5b324dd32d6e4b3efdc73 Mon Sep 17 00:00:00 2001 From: "Paulus H.J. Schulinck" Date: Thu, 12 May 2022 20:19:15 +0100 Subject: [PATCH 07/18] editorial changes to the example idem --- ...layout_tab_layout_hotplug_ext_rtc_temp_sensor_test.py | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/examples/hotplug_sensor_examples/displayio_layout_tab_layout_hotplug_ext_rtc_temp_sensor_test.py b/examples/hotplug_sensor_examples/displayio_layout_tab_layout_hotplug_ext_rtc_temp_sensor_test.py index 40be9e0..76a771d 100644 --- a/examples/hotplug_sensor_examples/displayio_layout_tab_layout_hotplug_ext_rtc_temp_sensor_test.py +++ b/examples/hotplug_sensor_examples/displayio_layout_tab_layout_hotplug_ext_rtc_temp_sensor_test.py @@ -330,8 +330,9 @@ def connect_rtc(): """ Function gets a value from the external temperature sensor It only updates if the value has changed compared to the previous value - If no value obtained (for instance if the sensor is disconnected) - the function sets the page_4 label to a default text + A fixed text is set in pge4_lbl2.text. The variable temperature value is set in pge4_lbl3.text + If no value obtained (for instance if the sensor is disconnected), + the function sets the pge4_lbl to a default text and makes empty pge4_lbl2.text and pge4_lbl3.text """ @@ -449,8 +450,8 @@ def handle_dt(dt): a) if an rtc is present from the rtc; b) if using online NTP pool server then get the date and time from the function time.localtime This time.localtime has before been set with data from the NTP server. - In both cases the date and time will be set to the page3_lbl, lbl12 and lbl3 - If no (valid) date and time has been received then a default text will be shown on the page3_lbl + In both cases the date and time will be set to the pge3_lbl, pge3_lbl12 and pge3_lbl3 + If no (valid) date and time has been received then a default text will be shown on the pge3_lbl """ From 8b2bcd58702e670f88b6a89a911fcad529d902b2 Mon Sep 17 00:00:00 2001 From: "Paulus H.J. Schulinck" Date: Sat, 14 May 2022 00:07:23 +0100 Subject: [PATCH 08/18] mods to the example Mods necessary to eliminate global variables as much as possible. Deleted flags: rtc_present, t_sensor_present. Replaces them by tests like: 'if rtc is not None' --- ...layout_hotplug_ext_rtc_temp_sensor_test.py | 40 ++++++++----------- 1 file changed, 16 insertions(+), 24 deletions(-) diff --git a/examples/hotplug_sensor_examples/displayio_layout_tab_layout_hotplug_ext_rtc_temp_sensor_test.py b/examples/hotplug_sensor_examples/displayio_layout_tab_layout_hotplug_ext_rtc_temp_sensor_test.py index 76a771d..e2acf5f 100644 --- a/examples/hotplug_sensor_examples/displayio_layout_tab_layout_hotplug_ext_rtc_temp_sensor_test.py +++ b/examples/hotplug_sensor_examples/displayio_layout_tab_layout_hotplug_ext_rtc_temp_sensor_test.py @@ -4,7 +4,7 @@ """ Make a PageLayout and illustrate all of it's features """ -# pylint: disable-all +# pylint: disable=global-statement import time import displayio import board @@ -64,7 +64,6 @@ lStart = True -rtc_present = None rtc = None o_secs = 0 # old seconds c_secs = 0 # current seconds @@ -74,7 +73,6 @@ sDT_old = "" -t_sensor_present = None tmp117 = None t0 = None t1 = None @@ -215,7 +213,7 @@ if board.board_id == "pyportal_titano": pages = {0: "Dum", 1: "One", 2: "Two", 3: "Three", 4: "Four"} else: - pages = {0: "Dum", 1: "One", 2: "Two", 3: "Thr", 3: "For"} + pages = {0: "Dum", 1: "One", 2: "Two", 3: "Thr", 4: "For"} # add the pages to the layout, supply your own page names test_page_layout.add_content(pge1_group, pages[1]) @@ -269,9 +267,9 @@ def connect_temp_sensor(): - global t_sensor_present, tmp117, t0, t1, t2 + global tmp117, t0, t1, t2 t = "temperature sensor found" - t_sensor_present = False + tmp117 = None try: @@ -280,9 +278,6 @@ def connect_temp_sensor(): pass if tmp117 is not None: - t_sensor_present = True - - if t_sensor_present: print(t) print("temperature sensor connected") t0 = "Temperature" @@ -299,15 +294,13 @@ def connect_temp_sensor(): """ If the external rtc has been disconnected, this function will try to reconnect (test if the external rtc is present by now) - If reconnected this function sets the global variable rtc_present - If failed to reconnect the function clears rtc_present """ def connect_rtc(): - global rtc_present, rtc, lStart + global rtc, lStart t = "RTC found" - rtc_present = False + rtc = None try: rtc = DS3231(i2c) # i2c addres 0x68 @@ -315,7 +308,6 @@ def connect_rtc(): pass if rtc is not None: - rtc_present = True print(t) print("RTC connected") if lStart: @@ -332,15 +324,17 @@ def connect_rtc(): It only updates if the value has changed compared to the previous value A fixed text is set in pge4_lbl2.text. The variable temperature value is set in pge4_lbl3.text If no value obtained (for instance if the sensor is disconnected), - the function sets the pge4_lbl to a default text and makes empty pge4_lbl2.text and pge4_lbl3.text + the function sets the pge4_lbl to a default text and makes empty + pge4_lbl2.text and pge4_lbl3.text """ def get_temp(): - global t_sensor_present, old_temp, tmp117, pge4_lbl, pge4_lbl2, pge4_lbl3, temp_in_REPL + global old_temp, tmp117, temp_in_REPL + showing_page_idx = test_page_layout.showing_page_index RetVal = False - if t_sensor_present: + if tmp117 is not None: try: temp = tmp117.temperature t = "{:5.2f} ".format(temp) + t1 @@ -367,7 +361,6 @@ def get_temp(): except OSError: print("Temperature sensor has disconnected") t = "" - t_sensor_present = False tmp117 = None pge4_lbl.text = pge4_lbl_dflt # clean the line (eventually: t2) pge4_lbl2.text = "" @@ -391,7 +384,7 @@ def get_temp(): def handle_dt(dt): - global pge3_lbl, pge3_lbl2, pge3_lbl3, o_secs, c_secs, dt_refresh, sDT_old + global o_secs, c_secs, dt_refresh, sDT_old RetVal = False s = "Date/time: " sYY = str(dt[yy]) @@ -456,18 +449,17 @@ def handle_dt(dt): def get_dt(): - global rtc_present, pge3_lbl, pge3_lbl2, pge3_lbl3 + dt = None RetVal = False - if rtc_present: + if rtc is not None: try: dt = rtc.datetime except OSError as exc: if my_debug: print("Error number: ", exc.args[0]) if exc.args[0] == 5: # Input/output error - rtc_present = False print("get_dt(): OSError occurred. RTC probably is disconnected") pge3_lbl.text = pge3_lbl_dflt return RetVal @@ -491,12 +483,12 @@ def main(): try: print("Loop nr: {:03d}".format(cnt)) - if rtc_present: + if rtc is not None: get_dt() else: connect_rtc() - if t_sensor_present: + if tmp117 is not None: get_temp() else: connect_temp_sensor() From 2e240323ff49008bfe9250fe66a19566837602fb Mon Sep 17 00:00:00 2001 From: "Paulus H.J. Schulinck" Date: Sat, 14 May 2022 20:22:15 +0100 Subject: [PATCH 09/18] example updated Now all globals used before are contained in an added gVars class. --- ...layout_hotplug_ext_rtc_temp_sensor_test.py | 349 ++++++++++++------ 1 file changed, 242 insertions(+), 107 deletions(-) diff --git a/examples/hotplug_sensor_examples/displayio_layout_tab_layout_hotplug_ext_rtc_temp_sensor_test.py b/examples/hotplug_sensor_examples/displayio_layout_tab_layout_hotplug_ext_rtc_temp_sensor_test.py index e2acf5f..97dd031 100644 --- a/examples/hotplug_sensor_examples/displayio_layout_tab_layout_hotplug_ext_rtc_temp_sensor_test.py +++ b/examples/hotplug_sensor_examples/displayio_layout_tab_layout_hotplug_ext_rtc_temp_sensor_test.py @@ -4,7 +4,7 @@ """ Make a PageLayout and illustrate all of it's features """ -# pylint: disable=global-statement + import time import displayio import board @@ -15,14 +15,138 @@ from adafruit_display_shapes.rect import Rect from adafruit_display_shapes.circle import Circle from adafruit_display_shapes.triangle import Triangle - -# from adafruit_bitmap_font import bitmap_font from adafruit_displayio_layout.layouts.tab_layout import TabLayout -# Adjust here the date and time that you want the RTC to be set at start: -default_dt = time.struct_time((2022, 5, 12, 18, 34, 0, 3, -1, -1)) +# +-------------------------------------------------------+ +# | Definition for variables in the past defined as global| +# +-------------------------------------------------------+ +# The gVars class is created +# to elminate the need for global variables. + + +class gVars: + def __init__(self): + + self.gVarsDict = { + 0: "my_debug", + 1: "rtc", + 2: "temp_sensor", + 3: "lStart", + 4: "o_secs", + 5: "c_secs", + 6: "dt_refresh", + 7: "sDT_old", + 8: "t0", + 9: "t1", + 10: "t2", + 11: "default_dt", + 12: "pge3_lbl_dflt", + 13: "pge4_lbl_dflt", + 14: "online_time_present", + 15: "temp_in_REPL", + 16: "old_temp", + 17: "use_ntp", + 18: "use_txt_in_month", + 19: "use_usa_notation", + 20: "content_sensor_idx", + } + + self.gVars_rDict = { + "my_debug": 0, + "rtc": 1, + "temp_sensor": 2, + "lStart": 3, + "o_secs": 4, + "c_secs": 5, + "dt_refresh": 6, + "sDT_old": 7, + "t0": 8, + "t1": 9, + "t2": 10, + "default_dt": 11, + "pge3_lbl_dflt": 12, + "pge4_lbl_dflt": 13, + "online_time_present": 14, + "temp_in_REPL": 15, + "old_temp": 16, + "use_ntp": 17, + "use_txt_in_month": 18, + "use_usa_notation": 19, + "content_sensor_idx": 20, + } + + self.g_vars = {} + + # self.clean() + + def write(self, s, value): + if isinstance(s, str): + if s in self.gVars_rDict: + n = self.gVars_rDict[s] + # print("myVars.write() \'{:" ">20s}\'found in self.gVars_rDict, + # key: {}".format(s, n)) + self.g_vars[n] = value + else: + raise KeyError( + "variable '{:" ">20s}' not found in self.gVars_rDict".format(s) + ) + else: + raise TypeError( + "myVars.write(): param s expected str, {} received".format(type(s)) + ) + + def read(self, s): + RetVal = None + if isinstance(s, str): + if s in self.gVars_rDict: + n = self.gVars_rDict[s] + if n in self.g_vars: + RetVal = self.g_vars[n] + return RetVal + + def clean(self): + self.g_vars = { + 0: None, + 1: None, + 2: None, + 3: None, + 4: None, + 5: None, + 6: None, + 7: None, + 8: None, + 9: None, + 10: None, + 11: None, + 12: None, + 13: None, + 14: None, + 15: None, + 16: None, + 17: None, + 18: None, + 19: None, + 20: None, + } + + def list(self): + for i in range(0, len(self.g_vars) - 1): + print( + "self.g_vars['{:" + ">20s}'] = {}".format( + self.gVarsDict[i], self.g_vars[i] if i in self.g_vars else "None" + ) + ) + + +# ---------- End of class gVars ------------------------ + +myVars = gVars() # create an instance of the gVars class + +myVars.write("my_debug", False) -my_debug = True +# Adjust here the date and time that you want the RTC to be set at start: +myVars.write("default_dt", time.struct_time((2022, 5, 14, 19, 42, 0, 5, -1, -1))) months = { 0: "Dum", @@ -40,16 +164,11 @@ 12: "Dec", } -use_txt_in_month = True -use_usa_notation = True -use_ntp = False - i2c = board.I2C() -if my_debug: +if myVars.read("my_debug"): while not i2c.try_lock(): pass - try: while True: print( @@ -58,34 +177,38 @@ ) time.sleep(2) break - finally: # unlock the i2c bus when ctrl-c'ing out of the loop i2c.unlock() - -lStart = True -rtc = None -o_secs = 0 # old seconds -c_secs = 0 # current seconds - -# used to flag when more or less static elements in datetime stamp have to be refreshed -dt_refresh = True - -sDT_old = "" - -tmp117 = None -t0 = None -t1 = None -t2 = None +# -------------- Setting myVars elements ---------------------------------- +myVars.write("rtc", None) +myVars.write("temp_sensor", None) +myVars.write("lStart", True) +myVars.write("o_secs", 0) # old seconds +myVars.write("c_secs", 0) # current seconds +# dt_refresh is used to flag when more or less static elements +# in datetime stamp have to be refreshed +myVars.write("dt_refresh", True) +myVars.write("sDT_old", "") +myVars.write("t0", None) +myVars.write("t1", None) +myVars.write("t2", None) +# default_dt already set above +myVars.write("pge3_lbl_dflt", "The third page is fun!") +myVars.write("pge4_lbl_dflt", "The fourth page is where it's at") +myVars.write("online_time_present", False) +myVars.write("temp_in_REPL", False) +myVars.write("old_temp", 0.00) +myVars.write("use_txt_in_month", True) +myVars.write("use_usa_notation", True) +myVars.write("use_ntp", False) +myVars.write("content_sensor_idx", None) +# ------------------------------------------------------------------------- +if myVars.read("my_debug"): + # print list of all variables in myVars + myVars.list() # degs_sign = chr(186) # I preferred the real degrees sign which is: chr(176) - -content_sensor_idx = None -pge3_lbl_dflt = "The third page is fun!" -pge4_lbl_dflt = "The fourth page is where it's at" - -online_time_present = None - # ----------------------------------- # built-in display @@ -97,7 +220,7 @@ main_group = displayio.Group() display.show(main_group) -# font = bitmap_font.load_font("fonts/Helvetica-Bold-16.bdf") +# fon.gvars bitmap_font.load_font("fonts/Helvetica-Bold-16.bdf") font = terminalio.FONT # create the page layout @@ -147,7 +270,7 @@ pge3_lbl = Label( font=terminalio.FONT, scale=2, - text=pge3_lbl_dflt, # Will be "Date/time:" + text=myVars.read("pge3_lbl_dflt"), # Will be "Date/time:" anchor_point=(0, 0), anchored_position=(10, 10), ) @@ -168,7 +291,7 @@ pge4_lbl = Label( font=terminalio.FONT, scale=2, - text=pge4_lbl_dflt, + text=myVars.read("pge4_lbl_dflt"), anchor_point=(0, 0), anchored_position=(10, 10), ) @@ -254,9 +377,7 @@ anchored_position=(100, 100)) test_page_layout.showing_page_content.append(another_text) """ -print("starting loop") -old_temp = 0.00 """ If the temperature sensor has been disconnected, @@ -267,28 +388,31 @@ def connect_temp_sensor(): - global tmp117, t0, t1, t2 t = "temperature sensor found" - tmp117 = None + # myVars.write("temp_sensor",None) try: - tmp117 = adafruit_tmp117.TMP117(i2c) + myVars.write("temp_sensor", adafruit_tmp117.TMP117(i2c)) except ValueError: # ValueError occurs if the temperature sensor is not connected pass - if tmp117 is not None: + print( + "connect_temp_sensor(): type(temp_sensor) object = ", + type(myVars.read("temp_sensor")), + ) + if myVars.read("temp_sensor") is not None: print(t) print("temperature sensor connected") - t0 = "Temperature" - t1 = " C" - t2 = 27 * "_" + myVars.write("t0", "Temperature") + myVars.write("t1", " C") + myVars.write("t2", 27 * "_") else: print("no " + t) print("failed to connect temperature sensor") - t0 = None - t1 = None - t2 = None + myVars.write("t0", None) + myVars.write("t1", None) + myVars.write("t2", None) """ @@ -298,27 +422,28 @@ def connect_temp_sensor(): def connect_rtc(): - global rtc, lStart t = "RTC found" - rtc = None + # myVars.write("rtc",None) + try: - rtc = DS3231(i2c) # i2c addres 0x68 + myVars.write("rtc", DS3231(i2c)) # i2c addres 0x68 + # myVars.write("rtc",rtc) except ValueError: pass - if rtc is not None: + print("connect_rtc() type rtc object = ", type(myVars.read("rtc"))) + if myVars.read("rtc") is not None: print(t) print("RTC connected") - if lStart: - lStart = False - rtc.datetime = default_dt + if myVars.read("lStart"): + myVars.write("lStart", False) + myVars.read("rtc").datetime = myVars.read("default_dt") else: print("no " + t) print("Failed to connect RTC") -temp_in_REPL = False """ Function gets a value from the external temperature sensor It only updates if the value has changed compared to the previous value @@ -330,45 +455,54 @@ def connect_rtc(): def get_temp(): - global old_temp, tmp117, temp_in_REPL - showing_page_idx = test_page_layout.showing_page_index RetVal = False - if tmp117 is not None: + if myVars.read("temp_sensor") is not None: try: - temp = tmp117.temperature - t = "{:5.2f} ".format(temp) + t1 - if my_debug and temp is not None and not temp_in_REPL: - temp_in_REPL = True - print("get_temp(): {} {}".format(t0, t)) + temp = myVars.read("temp_sensor").temperature + t = "{:5.2f} ".format(temp) + myVars.read("t1") + if ( + myVars.read("my_debug") + and temp is not None + and not myVars.read("temp_in_REPL") + ): + myVars.write("temp_in_REPL", True) + print("get_temp(): {} {}".format(myVars.read("t0"), t)) if showing_page_idx == 3: # show temperature on most right Tab page if temp is not None: - if ( - temp != old_temp + if temp != myVars.read( + "old_temp" ): # Only update if there is a change in temperature - old_temp = temp - t = "{:5.2f} ".format(temp) + t1 + myVars.write("old_temp", temp) + t = "{:5.2f} ".format(temp) + myVars.read("t1") pge4_lbl.text = "" - pge4_lbl2.text = t0 + pge4_lbl2.text = myVars.read("t0") pge4_lbl3.text = t # if not my_debug: - # print("pge4_lbl.text = {}".format(pge4_lbl.text)) + # print("pge4_lbl.tex.gvars {}".format(pge4_lbl.text)) # time.sleep(2) RetVal = True else: t = "" - pge4_lbl.text = pge4_lbl_dflt + pge4_lbl.text = myVars.read("pge4_lbl_dflt") except OSError: print("Temperature sensor has disconnected") t = "" - tmp117 = None - pge4_lbl.text = pge4_lbl_dflt # clean the line (eventually: t2) + myVars.write("temp_sensor", None) + pge4_lbl.text = myVars.read( + "pge4_lbl_dflt" + ) # clean the line (eventually: t2) pge4_lbl2.text = "" pge4_lbl3.text = "" return RetVal +""" + Function called by get_dt() + Created to repair pylint error R0912: Too many branches (13/12) +""" + yy = 0 mo = 1 dd = 2 @@ -377,20 +511,14 @@ def get_temp(): ss = 5 -""" - Function called by get_dt() - Created to repair pylint error R0912: Too many branches (13/12) -""" - - def handle_dt(dt): - global o_secs, c_secs, dt_refresh, sDT_old + RetVal = False s = "Date/time: " sYY = str(dt[yy]) sMO = ( months[dt[mo]] - if use_txt_in_month + if myVars.read("use_txt_in_month") else "0" + str(dt[mo]) if dt[mo] < 10 else str(dt[mo]) @@ -401,33 +529,34 @@ def handle_dt(dt): for _ in range(dd, ss + 1): dt_dict[_] = "0" + str(dt[_]) if dt[_] < 10 else str(dt[_]) - if my_debug: + if myVars.read("my_debug"): print("dt_dict = ", dt_dict) - c_secs = dt_dict[ss] + myVars.write("c_secs", dt_dict[ss]) sDT = ( sMO + "-" + dt_dict[dd] + "-" + sYY - if use_usa_notation + if myVars.read("use_usa_notation") else sYY + "-" + sMO + "-" + dt_dict[dd] ) - - if sDT_old != sDT: - sDT_old = sDT - dt_refresh = True # The date has changed, set the refresh flag + if myVars.read("my_debug"): + print("handle_dt(): sDT_old = {}, sDT = {}".format(myVars.read("sDT_old"), sDT)) + if myVars.read("sDT_old") != sDT: + myVars.write("sDT_old", sDT) + myVars.write("dt_refresh", True) # The date has changed, set the refresh flag sDT2 = dt_dict[hh] + ":" + dt_dict[mm] + ":" + dt_dict[ss] - if dt_refresh: # only refresh when needed - dt_refresh = False + if myVars.read("dt_refresh"): # only refresh when needed + myVars.write("dt_refresh", False) pge3_lbl.text = s pge3_lbl2.text = sDT - if c_secs != o_secs: - o_secs = c_secs + if myVars.read("c_secs") != myVars.read("o_secs"): + myVars.write("o_secs", myVars.read("c_secs")) sDT3 = s + "{} {}".format(sDT, sDT2) print(sDT3) pge3_lbl3.text = sDT2 - if my_debug: + if myVars.read("my_debug"): print("pge3_lbl.text = {}".format(pge3_lbl.text)) print("pge3_lbl2.text = {}".format(pge3_lbl2.text)) print("pge3_lbl3.text = {}".format(pge3_lbl3.text)) @@ -449,50 +578,56 @@ def handle_dt(dt): def get_dt(): - dt = None RetVal = False - if rtc is not None: + if myVars.read("rtc") is not None: try: - dt = rtc.datetime + dt = myVars.read("rtc").datetime except OSError as exc: - if my_debug: + if myVars.read("my_debug"): print("Error number: ", exc.args[0]) if exc.args[0] == 5: # Input/output error print("get_dt(): OSError occurred. RTC probably is disconnected") - pge3_lbl.text = pge3_lbl_dflt + pge3_lbl.text = myVars.read("pge3_lbl_dflt") + myVars.write("sDT_old", "") + pge3_lbl2.text = "" + pge3_lbl3.text = "" return RetVal raise # Handle other errors - elif online_time_present or use_ntp: + elif myVars.read("online_time_present") or myVars.read("use_ntp"): dt = time.localtime() + if myVars.read("my_debug"): + print("get_dt(): dt = ", dt) if dt is not None: RetVal = handle_dt(dt) else: - pge3_lbl.text = pge3_lbl_dflt + pge3_lbl.text = myVars.read("pge3_lbl_dflt") pge3_lbl2.text = "" pge3_lbl3.text = "" return RetVal +print("starting loop") + + def main(): cnt = 0 while True: try: print("Loop nr: {:03d}".format(cnt)) - - if rtc is not None: + # print("main(): type(rtc) object = ", type(myVars.read("rtc"))) + if myVars.read("rtc") is not None: get_dt() else: connect_rtc() - - if tmp117 is not None: + # print("main(): type(temp_sensor) object = ", type(myVars.read("temp_sensor"))) + if myVars.read("temp_sensor") is not None: get_temp() else: connect_temp_sensor() - cnt += 1 if cnt > 999: cnt = 0 From 3ecb29387058010352d296a7938fc99475559ac0 Mon Sep 17 00:00:00 2001 From: "Paulus H.J. Schulinck" Date: Sun, 15 May 2022 15:25:16 +0100 Subject: [PATCH 10/18] added example Example using datetime from NTP server, Touch interface. Using gVars class to set/get globally used variables. --- ...or_datetime_fm_NTP_touch_and_gVars_test.py | 997 ++++++++++++++++++ 1 file changed, 997 insertions(+) create mode 100644 examples/hotplug_sensor_examples/displayio_layout_tablayout_hotplug_temp_sensor_datetime_fm_NTP_touch_and_gVars_test.py diff --git a/examples/hotplug_sensor_examples/displayio_layout_tablayout_hotplug_temp_sensor_datetime_fm_NTP_touch_and_gVars_test.py b/examples/hotplug_sensor_examples/displayio_layout_tablayout_hotplug_temp_sensor_datetime_fm_NTP_touch_and_gVars_test.py new file mode 100644 index 0000000..d3c6789 --- /dev/null +++ b/examples/hotplug_sensor_examples/displayio_layout_tablayout_hotplug_temp_sensor_datetime_fm_NTP_touch_and_gVars_test.py @@ -0,0 +1,997 @@ +# SPDX-FileCopyrightText: 2022 PaulskPt +# +# SPDX-License-Identifier: MIT +""" +Notes by @PaulskPt: tested on an Adafruit PyPortal Titano +(Product ID 4444. See: https://www.adafruit.com/product/4444) +This script can make use of an I2C Realtime Clock type DS3231 +When the flag 'use_ntp' is set, the DS3231 will not be used, +instead the NTP class from adafruit_ntp.py will be used. +""" + +import time + +# import gc +import board +import busio +import displayio +import terminalio +import adafruit_tmp117 +from adafruit_ds3231 import DS3231 +from digitalio import DigitalInOut +import neopixel +import adafruit_touchscreen +from adafruit_esp32spi import adafruit_esp32spi +from adafruit_ntp import NTP +from adafruit_pyportal import PyPortal +from adafruit_display_text.bitmap_label import Label +from adafruit_display_shapes.rect import Rect +from adafruit_display_shapes.circle import Circle +from adafruit_display_shapes.triangle import Triangle +from adafruit_bitmap_font import bitmap_font +from adafruit_displayio_layout.layouts.tab_layout import TabLayout + +# +-------------------------------------------------------+ +# | Definition for variables in the past defined as global| +# +-------------------------------------------------------+ +# The gVars class is created +# to elminate the need for global variables. + + +class gVars: + def __init__(self): + + self.gVarsDict = { + 0: "my_debug", + 1: "rtc", + 2: "temp_sensor", + 3: "lStart", + 4: "o_secs", + 5: "c_secs", + 6: "dt_refresh", + 7: "sDT_old", + 8: "t0", + 9: "t1", + 10: "t2", + 11: "default_dt", + 12: "pge3_lbl_dflt", + 13: "pge4_lbl_dflt", + 14: "online_time_present", + 15: "temp_in_REPL", + 16: "old_temp", + 17: "use_ntp", + 18: "use_txt_in_month", + 19: "use_usa_notation", + 20: "content_sensor_idx", + 21: "ntp_refresh", + 22: "nHH_old", + 23: "next_NTP_sync", + 24: "s_cnt", + 25: "five_min_cnt", + 26: "next_NTP_sync_t1", + 27: "next_NTP_sync_t3", + } + + self.gVars_rDict = { + "my_debug": 0, + "rtc": 1, + "temp_sensor": 2, + "lStart": 3, + "o_secs": 4, + "c_secs": 5, + "dt_refresh": 6, + "sDT_old": 7, + "t0": 8, + "t1": 9, + "t2": 10, + "default_dt": 11, + "pge3_lbl_dflt": 12, + "pge4_lbl_dflt": 13, + "online_time_present": 14, + "temp_in_REPL": 15, + "old_temp": 16, + "use_ntp": 17, + "use_txt_in_month": 18, + "use_usa_notation": 19, + "content_sensor_idx": 20, + "ntp_refresh": 21, + "nHH_old": 22, + "next_NTP_sync": 23, + "s_cnt": 24, + "five_min_cnt": 25, + "next_NTP_sync_t1": 26, + "next_NTP_sync_t3": 27, + } + + self.g_vars = {} + + # self.clean() + + def write(self, s, value): + if isinstance(s, str): + if s in self.gVars_rDict: + n = self.gVars_rDict[s] + # print("myVars.write() \'{:" ">20s}\'found in self.gVars_rDict, + # key: {}".format(s, n)) + self.g_vars[n] = value + else: + raise KeyError( + "variable '{:" ">20s}' not found in self.gVars_rDict".format(s) + ) + else: + raise TypeError( + "myVars.write(): param s expected str, {} received".format(type(s)) + ) + + def read(self, s): + RetVal = None + if isinstance(s, str): + if s in self.gVars_rDict: + n = self.gVars_rDict[s] + if n in self.g_vars: + RetVal = self.g_vars[n] + return RetVal + + def clean(self): + self.g_vars = { + 0: None, + 1: None, + 2: None, + 3: None, + 4: None, + 5: None, + 6: None, + 7: None, + 8: None, + 9: None, + 10: None, + 11: None, + 12: None, + 13: None, + 14: None, + 15: None, + 16: None, + 17: None, + 18: None, + 19: None, + 20: None, + 21: None, + 22: None, + 23: None, + 24: None, + 25: None, + 26: None, + 27: None, + } + + def list(self): + for i in range(0, len(self.g_vars) - 1): + print( + "self.g_vars['{:" + ">20s}'] = {}".format( + self.gVarsDict[i], self.g_vars[i] if i in self.g_vars else "None" + ) + ) + + +# ---------- End of class gVars ------------------------ + +myVars = gVars() # create an instance of the gVars class + +myVars.write("my_debug", False) + +# Adjust here the date and time that you want the RTC to be set at start: +myVars.write("default_dt", time.struct_time((2022, 5, 14, 11, 42, 0, 5, -1, -1))) + +# start_time = time.monotonic() + +# -------------- Setting myVars elements ---------------------------------- +myVars.write("rtc", None) +myVars.write("temp_sensor", None) +myVars.write("lStart", True) +myVars.write("o_secs", 0) # old seconds +myVars.write("c_secs", 0) # current seconds +# dt_refresh is used to flag when more or less static elements +# in datetime stamp have to be refreshed +myVars.write("dt_refresh", True) +myVars.write("sDT_old", "") +myVars.write("t0", None) +myVars.write("t1", None) +myVars.write("t2", None) +# default_dt already set above +myVars.write("pge3_lbl_dflt", "The third page is fun!") +myVars.write("pge4_lbl_dflt", "The fourth page is where it's at") +myVars.write("online_time_present", False) +myVars.write("temp_in_REPL", False) +myVars.write("old_temp", 0.00) +myVars.write("use_txt_in_month", True) +myVars.write("use_usa_notation", True) +myVars.write("use_ntp", True) +myVars.write("content_sensor_idx", None) +myVars.write("ntp_refresh", True) +myVars.write("next_NTP_sync", 0) +myVars.write("s_cnt", 0) +myVars.write("five_min_cnt", 0) +myVars.write("next_NTP_sync_t1", "Next NTP sync in ") +myVars.write("next_NTP_sync_t3", " (mm:ss)") +# nHH_old is used to check if the hour has changed. +# If so we have to re-sync from NTP server +# (if not using an external RTC) +myVars.write("nHH_old", -1) + +if myVars.read("my_debug"): + # print list of all variables in myVars + myVars.list() +# ------------------------------------------------------------------------- +# degs_sign = chr(186) # I preferred the real degrees sign which is: chr(176) + +# If you are using a board with pre-defined ESP32 Pins: +esp32_cs = DigitalInOut(board.ESP_CS) +esp32_ready = DigitalInOut(board.ESP_BUSY) +esp32_reset = DigitalInOut(board.ESP_RESET) + +spi = busio.SPI(board.SCK, board.MOSI, board.MISO) +esp = adafruit_esp32spi.ESP_SPIcontrol(spi, esp32_cs, esp32_ready, esp32_reset) + +# ---------- Text Boxes ------------- # +# Set the font and preload letters +font_arial = bitmap_font.load_font( + "/fonts/Arial-16.bdf" +) # was: Helvetica-Bold-16.bdf") +# font.load_glyphs(b"abcdefghjiklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890- ()") +glyphs = b' "(),-.0123456789:ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz' +font_arial.load_glyphs(glyphs) +font_arial.load_glyphs(("°",)) # a non-ascii character we need +# gc.collect() # ADDED by @PaulskPt -- to prevent MemoryError - memory allocation failed, +# allocating 6444 bytes + +# ------------- Screen Setup ------------- # +pyportal = None +timeout_cnt = 0 +while pyportal is None: + try: + pyportal = PyPortal( + esp=esp, external_spi=spi, debug=True + ) # esp=esp, external_spi=spi) # create a PyPortal object + if pyportal is not None: + break + except ValueError: # Occurred the error: "SCK in use". + # Also occurred the error "SPEAKER_ENABLE in use" + time.sleep(0.5) + timeout_cnt += 1 + if timeout_cnt > 10: + print("Timeout occurred while trying to create a PyPortal object") + raise + +months = { + 0: "Dum", + 1: "Jan", + 2: "Feb", + 3: "Mar", + 4: "Apr", + 5: "May", + 6: "Jun", + 7: "Jul", + 8: "Aug", + 9: "Sep", + 10: "Oct", + 11: "Nov", + 12: "Dec", +} + +i2c = board.I2C() + +if myVars.read("use_ntp"): + print( + "\ntest_page_layout.showing_page_index test with I2C Temperature sensor and NTP \ +synchronized local time" + ) +else: + print("\nTabLayout test with I2C Temperature sensor and I2C Realtime clock") +print("Add your WiFi SSID, WiFi password and Timezone in file: secrets.h\n") + +if myVars.read("my_debug"): + while not i2c.try_lock(): + pass + + try: + while True: + print( + "I2C addresses found:", + [hex(device_address) for device_address in i2c.scan()], + ) + time.sleep(2) + break + + finally: # unlock the i2c bus when ctrl-c'ing out of the loop + i2c.unlock() + +# -------- Setting up SDCard --------------------- +# Is not needed to be done here: the SPI module is taking care of initializing the SD Card. +# See: https://andyfelong.com/2019/07/pyportal-access-the-micro-sd-card/#:~:text= \ +# It%20also%20has%20support%20for%20a%20micro%2DSD%20Card.&text=Software%20support%20 \ +# for%20PyPortal%20is, \ +# %2Din%20serial%2Dport%20terminal.77 +# +# NOTE: there is also the board.SD_CARD_DETECT pin (33)(but I don't know yet how to interface it) +#### + +# you'll need to pass in an io username and key +# Get wifi details and more from a secrets.py file +try: + from secrets import secrets +except ImportError: + print("WiFi secrets are kept in secrets.py, please add them there!") + raise + +if myVars.read("my_debug"): + if esp.status == adafruit_esp32spi.WL_IDLE_STATUS: + print("ESP32 found and in idle mode") + print("Firmware vers.", esp.firmware_version) + print("MAC addr:", [hex(i) for i in esp.MAC_address]) + + for ap in esp.scan_networks(): + print("\t%s\t\tRSSI: %d" % (str(ap["ssid"], "utf-8"), ap["rssi"])) + +# Get our username, key and desired timezone +location = secrets.get("timezone", None) + +print("\nConnecting to AP...") +while not esp.is_connected: + try: + esp.connect_AP(secrets["ssid"], secrets["password"]) + except RuntimeError as e: + print("could not connect to AP, retrying: ", e) + continue +print("Connected to", str(esp.ssid, "utf-8"), "\tRSSI:", esp.rssi) +print("Please wait...") +if myVars.read("my_debug"): + print("My IP address is", esp.pretty_ip(esp.ip_address)) + print( + "IP lookup adafruit.com: %s" + % esp.pretty_ip(esp.get_host_by_name("adafruit.com")) + ) + print("Ping google.com: %d ms" % esp.ping("google.com")) + + +def refresh_from_NTP(): + # Fetch and set the microcontroller's current UTC time + # keep retrying until a valid time is returned + timeout_cnt2 = 0 + while not ntp.valid_time: + ntp.set_time(tz_offset) + if myVars.read("my_debug"): + print("Failed to obtain time, retrying in 5 seconds...") + timeout_cnt2 += 1 + time.sleep(5) + if timeout_cnt2 > 10: + print("Timeout while trying to get ntp datetime to set the internal rtc") + break + if myVars.read("my_debug"): + print("Value ntp.valid_time = ", ntp.valid_time) + if ntp.valid_time: + myVars.write("online_time_present", True) + myVars.write("ntp_refresh", False) + # Get the current time in seconds since Jan 1, 1970 and correct it for local timezone + # (defined in secrets.h) + ntp_current_time = time.time() + if myVars.read("my_debug"): + print("Seconds since Jan 1, 1970: {} seconds".format(ntp_current_time)) + # Convert the current time in seconds since Jan 1, 1970 to a struct_time + myVars.write("default_dt", time.localtime(ntp_current_time)) + if not myVars.read("my_debug"): + print( + "Internal clock synchronized from NTP pool, now =", + myVars.read("default_dt"), + ) + + +if myVars.read("use_ntp"): + # Initialize the NTP object + ntp = NTP(esp) + + location = secrets.get("timezone", location) + if myVars.read("my_debug"): + print("location (from secrets.h) = ", location) + if location == "Europe/Lisbon": + if myVars.read("my_debug"): + print("Using timezone Europe/Lisbon") + tz_offset = 3600 + else: + tz_offset = 0 + + refresh_from_NTP() + +pixel = neopixel.NeoPixel(board.NEOPIXEL, 1, brightness=1) +WHITE = 0xFFFFFF +RED = 0xFF0000 +YELLOW = 0xFFFF00 +GREEN = 0x00FF00 +BLUE = 0x0000FF +PURPLE = 0xFF00FF +BLACK = 0x000000 + +# ---------- Sound Effects ------------- # +soundDemo = "/sounds/sound.wav" +soundBeep = "/sounds/beep.wav" +soundTab = "/sounds/tab.wav" + +# ------------ Touchscreen setup --------------- # +# See: https://learn.adafruit.com/making-a-pyportal-user-interface-displayio/display +display = board.DISPLAY # create the display object +display.rotation = 0 +# screen_width = 320 +# screen_height = 240 +screen_width = display.width +screen_height = display.height +# -------Rotate 0: +# Note @PaulskPt dd 2022-05-13 +# After using a touchscreen calibration script, the values are as follows: +# (XL, YU, XR, YD) are: (6935, 10496, 60127, 57631) +ts = adafruit_touchscreen.Touchscreen( + board.TOUCH_XL, + board.TOUCH_XR, + board.TOUCH_YD, + board.TOUCH_YU, # #calibration=((5200, 59000), (5800, 57000)), + calibration=((6815, 60095), (10520, 58007)), + size=(screen_width, screen_height), +) # was: screen_width, screen_height +""" +# If Rotate is 90: +# -------Rotate 90: +ts = adafruit_touchscreen.Touchscreen(board.TOUCH_YU, board.TOUCH_YD, + board.TOUCH_XL, board.TOUCH_XR, + calibration=((5200, 59000), (5800, 57000)), + size=(screen_height, screen_width)) +# If Rotate 180: +ts = adafruit_touchscreen.Touchscreen(board.TOUCH_XR, board.TOUCH_XL, + board.TOUCH_YU, board.TOUCH_YD, + calibration=((5200, 59000), (5800, 57000)), + size=(screen_width, screen_height)) + +# If Rotate 270: +ts = adafruit_touchscreen.Touchscreen(board.TOUCH_XL, board.TOUCH_XR, + board.TOUCH_YD, board.TOUCH_YU, + calibration=((5200, 59000), (5800, 57000)), + size=(screen_height, screen_width)) +""" +# ----------------------------------- + +# create and show main_group +main_group = displayio.Group() # The Main Display Group + +display.show(main_group) + +# font = bitmap_font.load_font("fonts/Helvetica-Bold-16.bdf") +# font = bitmap_font.load_font("/fonts/Arial-16.bdf") +font = terminalio.FONT + +# create the page layout +test_page_layout = TabLayout( + x=0, + y=0, + display=board.DISPLAY, + tab_text_scale=2, + custom_font=font, + inactive_tab_spritesheet="lib/adafruit_displayio_layout/examples/bmps/inactive_tab_sprite.bmp", + showing_tab_spritesheet="lib/adafruit_displayio_layout/examples/bmps/active_tab_sprite.bmp", + showing_tab_text_color=0x00AA59, + inactive_tab_text_color=0xEEEEEE, + inactive_tab_transparent_indexes=(0, 1), + showing_tab_transparent_indexes=(0, 1), + tab_count=4, +) +# make 4 pages of content +pge1_group = displayio.Group() +pge2_group = displayio.Group() +pge3_group = displayio.Group() +pge4_group = displayio.Group() +# make 1 background group +bg_group = displayio.Group() + +""" + From: https://learn.adafruit.com/making-a-pyportal-user-interface-displayio/the-full-code +""" + +# This will handle switching Images and Icons +def set_image(group, filename): + """Set the image file for a given goup for display. + This is most useful for Icons or image slideshows. + :param group: The chosen group + :param filename: The filename of the chosen image + """ + print("Set image to ", filename) + if group: + group.pop() + if not filename: + return # we're done, no icon desired + # CircuitPython 6 & 7 compatible + image_file = None + try: + # image_file = open(filename, "rb") + with open(filename, "rb") as image_file: + image = displayio.OnDiskBitmap(image_file) + except OSError as exc: + if exc.args[0] == 2: # No such file/directory + return + finally: + if image_file is not None: + image_file.close() + + image_sprite = displayio.TileGrid( + image, pixel_shader=getattr(image, "pixel_shader", displayio.ColorConverter()) + ) + + # # CircuitPython 7+ compatible + # image = displayio.OnDiskBitmap(filename) + # image_sprite = displayio.TileGrid(image, pixel_shader=image.pixel_shader) + main_group.append(image_sprite) + + +# ------------- Setup for Images ------------- # +bg_group = displayio.Group() +set_image(bg_group, "/images/BGimage4.bmp") +print( + "Please wait...building-up things..." +) # 2022-05-08 13h19 (utc+1) It takes 24 seconds from here to start of main() loop +main_group.append(bg_group) + +icon_group = displayio.Group() +icon_group.x = 180 +icon_group.y = 120 +icon_group.scale = 1 +pge2_group.append(icon_group) + +# labels +pge1_lbl = Label( + font=terminalio.FONT, + scale=2, + text="This is the first page!", + anchor_point=(0, 0), + anchored_position=(10, 10), +) +pge1_lbl2 = Label( + font=terminalio.FONT, + scale=2, + text="Please wait...", + anchor_point=(0, 0), + anchored_position=(10, 150), +) +pge2_lbl = Label( + font=terminalio.FONT, + scale=2, + text="This page is the second page!", + anchor_point=(0, 0), + anchored_position=(10, 10), +) +pge3_lbl = Label( + font=terminalio.FONT, + scale=2, + text=myVars.read("pge3_lbl_dflt"), # Will be "Date/time:" + anchor_point=(0, 0), + anchored_position=(10, 10), +) +pge3_lbl2 = Label( + font=terminalio.FONT, + scale=2, + text="", # pge3_lbl2_dflt, # Will be DD-MO-YYYY or Month-DD-YYYY + anchor_point=(0, 0), + anchored_position=(10, 40), +) +pge3_lbl3 = Label( + font=terminalio.FONT, + scale=2, + text="", # pge3_lbl3_dflt, # Will be HH:MM:SS + anchor_point=(0, 0), + anchored_position=(10, 70), +) +pge3_lbl4 = Label( + font=terminalio.FONT, + scale=2, + text="", # pge3_lbl3_dflt, # Will be time until next NTP sync in MM:SS + anchor_point=(0, 0), + anchored_position=(10, 200), +) +pge4_lbl = Label( + font=terminalio.FONT, + scale=2, + text=myVars.read("pge4_lbl_dflt"), + anchor_point=(0, 0), + anchored_position=(10, 10), +) +pge4_lbl2 = Label( + font=terminalio.FONT, + scale=2, + text="", # Will be "Temperature" + anchor_point=(0, 0), + anchored_position=(10, 130), +) + +pge4_lbl3 = Label( + font=font_arial, + scale=2, + text="", # Will be "xx.yy ºC" + anchor_point=(0, 0), + anchored_position=(10, 160), +) + +# shapes +square = Rect(x=20, y=70, width=40, height=40, fill=0x00DD00) +circle = Circle(50, 100, r=30, fill=0xDD00DD) +triangle = Triangle(50, 0, 100, 50, 0, 50, fill=0xDDDD00) +rectangle = Rect(x=80, y=60, width=100, height=50, fill=0x0000DD) +triangle.x = 80 +triangle.y = 70 + +# add everything to their page groups +pge1_group.append(square) +pge1_group.append(pge1_lbl) +pge1_group.append(pge1_lbl2) +pge2_group.append(pge2_lbl) +pge2_group.append(circle) +pge3_group.append(pge3_lbl) +pge3_group.append(pge3_lbl2) +pge3_group.append(pge3_lbl3) +pge3_group.append(pge3_lbl4) +pge3_group.append(triangle) +pge4_group.append(pge4_lbl) +pge4_group.append(pge4_lbl2) +pge4_group.append(pge4_lbl3) +pge4_group.append(rectangle) + +if board.board_id == "pyportal_titano": + pages = {0: "Dum", 1: "One", 2: "Two", 3: "Three", 4: "Four"} +else: + pages = {0: "Dum", 1: "One", 2: "Two", 3: "Thr", 4: "For"} + +# add the pages to the layout, supply your own page names +test_page_layout.add_content(pge1_group, pages[1]) +test_page_layout.add_content(pge2_group, pages[2]) +test_page_layout.add_content(pge3_group, pages[3]) +test_page_layout.add_content(pge4_group, pages[4]) +# test_page_layout.add_content(displayio.Group(), "page_5") +# add it to the group that is showing on the display +main_group.append(test_page_layout) +# test_page_layout.tab_tilegrids_group[3].x += 50 +pge2_group = 1 + + +"""If the temperature sensor has been disconnected, + this function will try to reconnect (test if the sensor is present by now) + If reconnected this function creates the temp_sensor object""" + + +def connect_temp_sensor(): + t = "temperature sensor found" + + # myVars.write("temp_sensor",None) + + try: + myVars.write("temp_sensor", adafruit_tmp117.TMP117(i2c)) + except ValueError: # ValueError occurs if the temperature sensor is not connected + pass + + print( + "connect_temp_sensor(): type(temp_sensor) object = ", + type(myVars.read("temp_sensor")), + ) + if myVars.read("temp_sensor") is not None: + print(t) + print("temperature sensor connected") + myVars.write("t0", "Temperature") + myVars.write("t1", chr(186) + "C") + myVars.write("t2", 27 * "_") + else: + print("no " + t) + print("failed to connect temperature sensor") + myVars.write("t0", None) + myVars.write("t1", None) + myVars.write("t2", None) + + +"""If the external rtc has been disconnected, + this function will try to reconnect (test if the external rtc is present by now)""" + + +def connect_rtc(): + t = "RTC found" + + # myVars.write("rtc",None) + + try: + myVars.write("rtc", DS3231(i2c)) # i2c addres 0x68 + # myVars.write("rtc",rtc) + except ValueError: + pass + + print("connect_rtc() type rtc object = ", type(myVars.read("rtc"))) + if myVars.read("rtc") is not None: + print(t) + print("RTC connected") + if myVars.read("lStart"): + myVars.write("lStart", False) + myVars.read("rtc").datetime = myVars.read("default_dt") + else: + print("no " + t) + print("Failed to connect RTC") + + +"""Function gets a value from the external temperature sensor + It only updates if the value has changed compared to the previous value + A fixed text is set in pge4_lbl2.text. The variable temperature value is set in pge4_lbl3.text + If no value obtained (for instance if the sensor is disconnected), + the function sets the pge4_lbl to a default text and makes empty + pge4_lbl2.text and pge4_lbl3.text""" + + +def get_temp(): + my_debug = myVars.read("my_debug") + showing_page_idx = test_page_layout.showing_page_index + RetVal = False + if myVars.read("temp_sensor") is not None: + try: + temp = myVars.read("temp_sensor").temperature + t = "{:5.2f}{} ".format(temp, myVars.read("t1")) + if my_debug and temp is not None and not myVars.read("temp_in_REPL"): + myVars.write("temp_in_REPL", True) + print("get_temp(): {} {}".format(myVars.read("t0"), t)) + if showing_page_idx == 3: # show temperature on most right Tab page + if temp is not None: + if temp != myVars.read( + "old_temp" + ): # Only update if there is a change in temperature + myVars.write("old_temp", temp) + t = "{:5.2f}{} ".format(temp, myVars.read("t1")) + pge4_lbl.text = "" + pge4_lbl2.text = myVars.read("t0") + pge4_lbl3.text = t + # if not my_debug: + # print("pge4_lbl.tex.gvars {}".format(pge4_lbl.text)) + # time.sleep(2) + RetVal = True + else: + t = "" + pge4_lbl.text = myVars.read("pge4_lbl_dflt") + except OSError: + print("Temperature sensor has disconnected") + t = "" + myVars.write("temp_sensor", None) + pge4_lbl.text = myVars.read( + "pge4_lbl_dflt" + ) # clean the line (eventually: t2) + pge4_lbl2.text = "Sensor disconnected." + pge4_lbl3.text = "Check wiring." + + return RetVal + + +# Moved these six definitions outside handle_dt() +# to correct pylint error 'too many variables' +# dt_idxs = {0: "yy", 1:"mo", 2:"dd", 3:"hh", 4:"mm", 5:"ss"} +dt_ridxs = {"yy": 0, "mo": 1, "dd": 2, "hh": 3, "mm": 4, "ss": 5} + +# print("dict dt_ridxs =", dt_ridxs.keys()) + + +""" Function called by get_dt() + Created to repair pylint error R0912: Too many branches (13/12)""" + + +def handle_dt(dt): + my_debug = myVars.read("my_debug") + RetVal = False + s = "Date/time: " + sYY = str(dt[dt_ridxs["yy"]]) # was: str(dt[yy]) + # print("dt_ridxs["mo"] = ", dt_ridxs["mo"]) + # modified mo because plynt error R0914 'Too many local variables' + # mo = dt_ridxs["mo"] + dd = dt_ridxs["dd"] + hh = dt_ridxs["hh"] + mm = dt_ridxs["mm"] + ss = dt_ridxs["ss"] + if "mo" in dt_ridxs: + sMO = ( + months[dt_ridxs["mo"]] # was: months[dt[mo]] + if myVars.read("use_txt_in_month") + else "0" + str(dt[dt_ridxs["mo"]]) + if dt[dt_ridxs["mo"]] < 10 + else str(dt[dt_ridxs["mo"]]) + ) + else: + raise KeyError("key {} not in dt_ridxs dict".format("mo")) + + dt_dict = {} + + for _ in range(dd, ss + 1): + dt_dict[_] = "0" + str(dt[_]) if dt[_] < 10 else str(dt[_]) + + if my_debug: + print("dt_dict = ", dt_dict) + + myVars.write("c_secs", dt_dict[ss]) + sDT = ( + sMO + "-" + dt_dict[dd] + "-" + sYY + if myVars.read("use_usa_notation") + else sYY + "-" + sMO + "-" + dt_dict[dd] + ) + if my_debug: + print("handle_dt(): sDT_old = {}, sDT = {}".format(myVars.read("sDT_old"), sDT)) + if myVars.read("sDT_old") != sDT: + myVars.write("sDT_old", sDT) + myVars.write("dt_refresh", True) # The date has changed, set the refresh flag + sDT2 = dt_dict[hh] + ":" + dt_dict[mm] + ":" + dt_dict[ss] + + if myVars.read("dt_refresh"): # only refresh when needed + myVars.write("dt_refresh", False) + pge3_lbl.text = s + pge3_lbl2.text = sDT + + if myVars.read("c_secs") != myVars.read("o_secs"): + myVars.write("o_secs", myVars.read("c_secs")) + sDT3 = s + "{} {}".format(sDT, sDT2) + print(sDT3) + + pge3_lbl3.text = sDT2 + if my_debug: + print("pge3_lbl.text = {}".format(pge3_lbl.text)) + print("pge3_lbl2.text = {}".format(pge3_lbl2.text)) + print("pge3_lbl3.text = {}".format(pge3_lbl3.text)) + RetVal = True + + # Return from here with a False but don't set the pge3_lbl to default. + # It is only to say to the loop() that we did't update the datetime + return RetVal + + +""" Function gets the date and time: a) if an rtc is present from the rtc; + b) if using online NTP pool server then get the date and time from the function time.localtime + This time.localtime has before been set with data from the NTP server. + In both cases the date and time will be set to the pge3_lbl, pge3_lbl12 and pge3_lbl3 + If no (valid) datetime a default text will be shown on the pge3_lbl""" + + +def get_dt(): + dt = None + RetVal = False + + if myVars.read("rtc") is not None: + try: + dt = myVars.read("rtc").datetime + except OSError as exc: + if myVars.read("my_debug"): + print("Error number: ", exc.args[0]) + if exc.args[0] == 5: # Input/output error + print("get_dt(): OSError occurred. RTC probably is disconnected") + pge3_lbl.text = myVars.read("pge3_lbl_dflt") + myVars.write("sDT_old", "") + pge3_lbl2.text = "" + pge3_lbl3.text = "" + return RetVal + raise # Handle other errors + + elif myVars.read("online_time_present") or myVars.read("use_ntp"): + dt = time.localtime() + + if myVars.read("my_debug"): + print("get_dt(): dt = ", dt) + if dt is not None: + RetVal = handle_dt(dt) + else: + pge3_lbl.text = myVars.read("pge3_lbl_dflt") + pge3_lbl2.text = "" + pge3_lbl3.text = "" + return RetVal + + +""" hms_to_cnt() + function returns a integer value representing + the conversion from the current hours, minutes and seconds + into seconds""" + + +def hms_to_cnt(): + dt = time.localtime() # get the local time as a time_struct + return (dt.tm_hour * 3600) + (dt.tm_min * 60) + dt.tm_sec + + +""" Created this function to correct pylint errors: + 'Too many branches' R0912 and + 'Too many statements' R0915""" + + +def ck_next_NTP_sync(): + s_cnt = myVars.read("s_cnt") + c_cnt = hms_to_cnt() # set current count (seconds) + c_elapsed = c_cnt - s_cnt + if c_elapsed < 10: # continue only when c_elapsed >= 10 + return + + TAG = "ck_next_NTP_sync(): " + my_debug = myVars.read("my_debug") + t1 = myVars.read("next_NTP_sync_t1") + t3 = myVars.read("next_NTP_sync_t3") + five_min = myVars.read("five_min_cnt") + myVars.write("s_cnt", hms_to_cnt()) + + # --- five minutes count down calculations #1 --- + + if my_debug: + print( + TAG + "five_min = {}, s_cnt = {}, c_cnt = {}".format(five_min, s_cnt, c_cnt) + ) + print(TAG + "c_elapsed = ", c_elapsed) + + # --- five minutes count down calculations #2 --- + myVars.write("s_cnt", c_cnt) # remember c_cnt + five_min -= 10 + myVars.write("five_min_cnt", five_min) # remember count + mm2 = five_min // 60 + ss2 = five_min - (mm2 * 60) + t2 = "{:02d}:{:02d}".format(mm2, ss2) + t0 = t1 + t2 + t3 + print(t0) + pge3_lbl4.text = t0 + if five_min == 0: # five minutes passed + pge3_lbl4.text = "" + myVars.write("five_min_cnt", 300) # reset count + myVars.write("ntp_refresh", True) + + +def inc_cnt(cnt): + cnt += 1 + if cnt > 999: + cnt = 0 + return cnt + + +def main(): + cnt = 1 + wipe_pge1_lbl2_text = False + print("Starting loop") + pge1_lbl2.text = "Ready..." + myVars.write("five_min_cnt", 300) # 5 minutes + myVars.write("s_cnt", hms_to_cnt()) # set start count (seconds) + use_ntp = myVars.read("use_ntp") + rtc = myVars.read("rtc") + otp = myVars.read("online_time_present") + # print("Starting loop") + while True: + touch = ts.touch_point + try: + + if use_ntp: + ck_next_NTP_sync() + ntp_refresh = myVars.read("ntp_refresh") + # ------------- Handle Tab touch ------------- # + # print("main() value touch: ", touch) + if touch: # Only do this if the screen is touched + if not wipe_pge1_lbl2_text: + pge1_lbl2.text = "" # Clear the label + wipe_pge1_lbl2_text = True + test_page_layout.handle_touch_events(touch) + if rtc is not None or otp: + if otp and ntp_refresh: + refresh_from_NTP() # first re-synchronize internal clock from NTP server + if get_dt(): + print("Loop nr: {:03d}".format(cnt)) + else: + connect_rtc() + if myVars.read("temp_sensor") is not None: + get_temp() + else: + connect_temp_sensor() + touch = ( + ts.touch_point + ) # Just to try - it looks like after re-connecting the sensor, + # the touch data has lost + if myVars.read("temp_in_REPL"): + myVars.write("temp_in_REPL", False) + + cnt = inc_cnt(cnt) + except KeyboardInterrupt as exc: + print("Keyboard interrupt...exiting...") + raise KeyboardInterrupt from exc + + +if __name__ == "__main__": + main() From cd46824244fbd6e083c0c75ef9b790ff106279c3 Mon Sep 17 00:00:00 2001 From: "Paulus H.J. Schulinck" Date: Sun, 15 May 2022 15:44:32 +0100 Subject: [PATCH 11/18] small correction in example bug repair --- ..._hotplug_temp_sensor_datetime_fm_NTP_touch_and_gVars_test.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/hotplug_sensor_examples/displayio_layout_tablayout_hotplug_temp_sensor_datetime_fm_NTP_touch_and_gVars_test.py b/examples/hotplug_sensor_examples/displayio_layout_tablayout_hotplug_temp_sensor_datetime_fm_NTP_touch_and_gVars_test.py index d3c6789..65b122c 100644 --- a/examples/hotplug_sensor_examples/displayio_layout_tablayout_hotplug_temp_sensor_datetime_fm_NTP_touch_and_gVars_test.py +++ b/examples/hotplug_sensor_examples/displayio_layout_tablayout_hotplug_temp_sensor_datetime_fm_NTP_touch_and_gVars_test.py @@ -791,7 +791,7 @@ def handle_dt(dt): ss = dt_ridxs["ss"] if "mo" in dt_ridxs: sMO = ( - months[dt_ridxs["mo"]] # was: months[dt[mo]] + months[dt[dt_ridxs["mo"]]] # was: months[dt[mo]] if myVars.read("use_txt_in_month") else "0" + str(dt[dt_ridxs["mo"]]) if dt[dt_ridxs["mo"]] < 10 From 9256ea98deda3fa2bb9788a9f3cb1a96f4dce5ac Mon Sep 17 00:00:00 2001 From: "Paulus H.J. Schulinck" Date: Sun, 15 May 2022 15:58:39 +0100 Subject: [PATCH 12/18] mod in .gitignore idem --- .gitignore | 1 - 1 file changed, 1 deletion(-) diff --git a/.gitignore b/.gitignore index 5247efd..544ec4a 100644 --- a/.gitignore +++ b/.gitignore @@ -45,4 +45,3 @@ _build .idea .vscode *~ -examples/hotplug_sensor_examples/images/BGimage4.bmp From f3d0ac11c8669759b19b33785144357646c50afa Mon Sep 17 00:00:00 2001 From: "Paulus H.J. Schulinck" Date: Sun, 15 May 2022 16:07:28 +0100 Subject: [PATCH 13/18] added image file Added BGimage4.bmp and it's .license file --- .../images/BGimage4.bmp | Bin 0 -> 530078 bytes .../images/BGimage4.bmp.license | 2 ++ 2 files changed, 2 insertions(+) create mode 100644 examples/hotplug_sensor_examples/images/BGimage4.bmp create mode 100644 examples/hotplug_sensor_examples/images/BGimage4.bmp.license diff --git a/examples/hotplug_sensor_examples/images/BGimage4.bmp b/examples/hotplug_sensor_examples/images/BGimage4.bmp new file mode 100644 index 0000000000000000000000000000000000000000..02d4c259878ca392426c9f0530e94918fb219cb6 GIT binary patch literal 530078 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 F{{a9$T9^O; literal 0 HcmV?d00001 diff --git a/examples/hotplug_sensor_examples/images/BGimage4.bmp.license b/examples/hotplug_sensor_examples/images/BGimage4.bmp.license new file mode 100644 index 0000000..82d4370 --- /dev/null +++ b/examples/hotplug_sensor_examples/images/BGimage4.bmp.license @@ -0,0 +1,2 @@ +# SPDX-FileCopyrightText: 2022 PaulskPt +# SPDX-License-Identifier: MIT From d52bbdfa134397376b82ccb23f7721b39f02b8a8 Mon Sep 17 00:00:00 2001 From: "Paulus H.J. Schulinck" Date: Sun, 15 May 2022 21:55:05 +0100 Subject: [PATCH 14/18] various mods in 2nd test script idem --- ...or_datetime_fm_NTP_touch_and_gVars_test.py | 120 +++++++++--------- 1 file changed, 59 insertions(+), 61 deletions(-) diff --git a/examples/hotplug_sensor_examples/displayio_layout_tablayout_hotplug_temp_sensor_datetime_fm_NTP_touch_and_gVars_test.py b/examples/hotplug_sensor_examples/displayio_layout_tablayout_hotplug_temp_sensor_datetime_fm_NTP_touch_and_gVars_test.py index 65b122c..4f8d9b1 100644 --- a/examples/hotplug_sensor_examples/displayio_layout_tablayout_hotplug_temp_sensor_datetime_fm_NTP_touch_and_gVars_test.py +++ b/examples/hotplug_sensor_examples/displayio_layout_tablayout_hotplug_temp_sensor_datetime_fm_NTP_touch_and_gVars_test.py @@ -2,16 +2,14 @@ # # SPDX-License-Identifier: MIT """ -Notes by @PaulskPt: tested on an Adafruit PyPortal Titano +Notes by @PaulskPt +Script tested on an Adafruit PyPortal Titano (Product ID 4444. See: https://www.adafruit.com/product/4444) This script can make use of an I2C Realtime Clock type DS3231 -When the flag 'use_ntp' is set, the DS3231 will not be used, +However, when the flag 'use_ntp' is set, the DS3231 will not be used instead the NTP class from adafruit_ntp.py will be used. """ - import time - -# import gc import board import busio import displayio @@ -31,6 +29,7 @@ from adafruit_bitmap_font import bitmap_font from adafruit_displayio_layout.layouts.tab_layout import TabLayout + # +-------------------------------------------------------+ # | Definition for variables in the past defined as global| # +-------------------------------------------------------+ @@ -233,18 +232,6 @@ def list(self): spi = busio.SPI(board.SCK, board.MOSI, board.MISO) esp = adafruit_esp32spi.ESP_SPIcontrol(spi, esp32_cs, esp32_ready, esp32_reset) -# ---------- Text Boxes ------------- # -# Set the font and preload letters -font_arial = bitmap_font.load_font( - "/fonts/Arial-16.bdf" -) # was: Helvetica-Bold-16.bdf") -# font.load_glyphs(b"abcdefghjiklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890- ()") -glyphs = b' "(),-.0123456789:ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz' -font_arial.load_glyphs(glyphs) -font_arial.load_glyphs(("°",)) # a non-ascii character we need -# gc.collect() # ADDED by @PaulskPt -- to prevent MemoryError - memory allocation failed, -# allocating 6444 bytes - # ------------- Screen Setup ------------- # pyportal = None timeout_cnt = 0 @@ -367,8 +354,10 @@ def refresh_from_NTP(): if timeout_cnt2 > 10: print("Timeout while trying to get ntp datetime to set the internal rtc") break + if myVars.read("my_debug"): print("Value ntp.valid_time = ", ntp.valid_time) + if ntp.valid_time: myVars.write("online_time_present", True) myVars.write("ntp_refresh", False) @@ -377,6 +366,7 @@ def refresh_from_NTP(): ntp_current_time = time.time() if myVars.read("my_debug"): print("Seconds since Jan 1, 1970: {} seconds".format(ntp_current_time)) + # Convert the current time in seconds since Jan 1, 1970 to a struct_time myVars.write("default_dt", time.localtime(ntp_current_time)) if not myVars.read("my_debug"): @@ -463,8 +453,8 @@ def refresh_from_NTP(): display.show(main_group) # font = bitmap_font.load_font("fonts/Helvetica-Bold-16.bdf") -# font = bitmap_font.load_font("/fonts/Arial-16.bdf") -font = terminalio.FONT +font_arial = bitmap_font.load_font("/fonts/Arial-16.bdf") +font_term = terminalio.FONT # create the page layout test_page_layout = TabLayout( @@ -472,7 +462,7 @@ def refresh_from_NTP(): y=0, display=board.DISPLAY, tab_text_scale=2, - custom_font=font, + custom_font=font_term, inactive_tab_spritesheet="lib/adafruit_displayio_layout/examples/bmps/inactive_tab_sprite.bmp", showing_tab_spritesheet="lib/adafruit_displayio_layout/examples/bmps/active_tab_sprite.bmp", showing_tab_text_color=0x00AA59, @@ -501,34 +491,29 @@ def set_image(group, filename): :param filename: The filename of the chosen image """ print("Set image to ", filename) + image = None + image_sprite = None if group: group.pop() if not filename: return # we're done, no icon desired # CircuitPython 6 & 7 compatible - image_file = None try: - # image_file = open(filename, "rb") - with open(filename, "rb") as image_file: - image = displayio.OnDiskBitmap(image_file) + image = displayio.OnDiskBitmap(filename) except OSError as exc: if exc.args[0] == 2: # No such file/directory return - finally: - if image_file is not None: - image_file.close() - - image_sprite = displayio.TileGrid( - image, pixel_shader=getattr(image, "pixel_shader", displayio.ColorConverter()) - ) - - # # CircuitPython 7+ compatible - # image = displayio.OnDiskBitmap(filename) - # image_sprite = displayio.TileGrid(image, pixel_shader=image.pixel_shader) - main_group.append(image_sprite) + if image is not None: + image_sprite = displayio.TileGrid( + image, + pixel_shader=getattr(image, "pixel_shader", displayio.ColorConverter()), + ) + if image_sprite is not None: + main_group.append(image_sprite) # ------------- Setup for Images ------------- # + bg_group = displayio.Group() set_image(bg_group, "/images/BGimage4.bmp") print( @@ -544,71 +529,70 @@ def set_image(group, filename): # labels pge1_lbl = Label( - font=terminalio.FONT, + font=font_term, scale=2, text="This is the first page!", anchor_point=(0, 0), anchored_position=(10, 10), ) pge1_lbl2 = Label( - font=terminalio.FONT, + font=font_term, scale=2, text="Please wait...", anchor_point=(0, 0), anchored_position=(10, 150), ) pge2_lbl = Label( - font=terminalio.FONT, + font=font_term, scale=2, text="This page is the second page!", anchor_point=(0, 0), anchored_position=(10, 10), ) pge3_lbl = Label( - font=terminalio.FONT, + font=font_term, scale=2, text=myVars.read("pge3_lbl_dflt"), # Will be "Date/time:" anchor_point=(0, 0), anchored_position=(10, 10), ) pge3_lbl2 = Label( - font=terminalio.FONT, + font=font_term, scale=2, text="", # pge3_lbl2_dflt, # Will be DD-MO-YYYY or Month-DD-YYYY anchor_point=(0, 0), anchored_position=(10, 40), ) pge3_lbl3 = Label( - font=terminalio.FONT, + font=font_term, scale=2, text="", # pge3_lbl3_dflt, # Will be HH:MM:SS anchor_point=(0, 0), anchored_position=(10, 70), ) pge3_lbl4 = Label( - font=terminalio.FONT, + font=font_term, scale=2, text="", # pge3_lbl3_dflt, # Will be time until next NTP sync in MM:SS anchor_point=(0, 0), anchored_position=(10, 200), ) pge4_lbl = Label( - font=terminalio.FONT, + font=font_term, scale=2, text=myVars.read("pge4_lbl_dflt"), anchor_point=(0, 0), anchored_position=(10, 10), ) pge4_lbl2 = Label( - font=terminalio.FONT, + font=font_term, scale=2, text="", # Will be "Temperature" anchor_point=(0, 0), anchored_position=(10, 130), ) - pge4_lbl3 = Label( - font=font_arial, + font=font_arial, # bitmap_font.load_font("/fonts/Arial-16.bdf"), scale=2, text="", # Will be "xx.yy ºC" anchor_point=(0, 0), @@ -620,6 +604,7 @@ def set_image(group, filename): circle = Circle(50, 100, r=30, fill=0xDD00DD) triangle = Triangle(50, 0, 100, 50, 0, 50, fill=0xDDDD00) rectangle = Rect(x=80, y=60, width=100, height=50, fill=0x0000DD) + triangle.x = 80 triangle.y = 70 @@ -653,12 +638,24 @@ def set_image(group, filename): # add it to the group that is showing on the display main_group.append(test_page_layout) # test_page_layout.tab_tilegrids_group[3].x += 50 +# ---------- Text Boxes ------------- # +# Set the font and preload letters +# font = bitmap_font.load_font("/fonts/Arial-16.bdf") # was: Helvetica-Bold-16.bdf") +# font.load_glyphs(b"abcdefghjiklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890- ()") +glyphs = b' "(),-.0123456789:ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz' +font_arial.load_glyphs(glyphs) +font_arial.load_glyphs(("°",)) # a non-ascii character we need +# gc.collect() # ADDED by @PaulskPt -- to prevent MemoryError - memory allocation failed, +# allocating 6444 bytes + pge2_group = 1 -"""If the temperature sensor has been disconnected, +""" + If the temperature sensor has been disconnected, this function will try to reconnect (test if the sensor is present by now) - If reconnected this function creates the temp_sensor object""" + If reconnected this function creates the temp_sensor object +""" def connect_temp_sensor(): @@ -689,8 +686,10 @@ def connect_temp_sensor(): myVars.write("t2", None) -"""If the external rtc has been disconnected, - this function will try to reconnect (test if the external rtc is present by now)""" +""" + If the external rtc has been disconnected, + this function will try to reconnect (test if the external rtc is present by now) +""" def connect_rtc(): @@ -716,12 +715,14 @@ def connect_rtc(): print("Failed to connect RTC") -"""Function gets a value from the external temperature sensor +""" + Function gets a value from the external temperature sensor It only updates if the value has changed compared to the previous value A fixed text is set in pge4_lbl2.text. The variable temperature value is set in pge4_lbl3.text If no value obtained (for instance if the sensor is disconnected), the function sets the pge4_lbl to a default text and makes empty - pge4_lbl2.text and pge4_lbl3.text""" + pge4_lbl2.text and pge4_lbl3.text +""" def get_temp(): @@ -761,7 +762,6 @@ def get_temp(): ) # clean the line (eventually: t2) pge4_lbl2.text = "Sensor disconnected." pge4_lbl3.text = "Check wiring." - return RetVal @@ -843,11 +843,14 @@ def handle_dt(dt): return RetVal -""" Function gets the date and time: a) if an rtc is present from the rtc; +""" + Function gets the date and time: + a) if an rtc is present from the rtc; b) if using online NTP pool server then get the date and time from the function time.localtime This time.localtime has before been set with data from the NTP server. In both cases the date and time will be set to the pge3_lbl, pge3_lbl12 and pge3_lbl3 - If no (valid) datetime a default text will be shown on the pge3_lbl""" + If no (valid) date and time has been received then a default text will be shown on the pge3_lbl +""" def get_dt(): @@ -905,16 +908,13 @@ def ck_next_NTP_sync(): c_elapsed = c_cnt - s_cnt if c_elapsed < 10: # continue only when c_elapsed >= 10 return - TAG = "ck_next_NTP_sync(): " my_debug = myVars.read("my_debug") t1 = myVars.read("next_NTP_sync_t1") t3 = myVars.read("next_NTP_sync_t3") five_min = myVars.read("five_min_cnt") myVars.write("s_cnt", hms_to_cnt()) - # --- five minutes count down calculations #1 --- - if my_debug: print( TAG + "five_min = {}, s_cnt = {}, c_cnt = {}".format(five_min, s_cnt, c_cnt) @@ -958,7 +958,6 @@ def main(): while True: touch = ts.touch_point try: - if use_ntp: ck_next_NTP_sync() ntp_refresh = myVars.read("ntp_refresh") @@ -986,7 +985,6 @@ def main(): # the touch data has lost if myVars.read("temp_in_REPL"): myVars.write("temp_in_REPL", False) - cnt = inc_cnt(cnt) except KeyboardInterrupt as exc: print("Keyboard interrupt...exiting...") From 417c80acdb5e1d094ffbdfd897e96dc43572c039 Mon Sep 17 00:00:00 2001 From: "Paulus H.J. Schulinck" Date: Mon, 16 May 2022 14:11:39 +0100 Subject: [PATCH 15/18] second example added flag "temp_in_fahrenheit" In gVars class added flag "temp_in_fahrenheit". In second example modified algorithm to display the temperature sensor value in degrees Celsius or in degrees Fahrenheit depending the flag. See lines 211 , 667-670 and 725-726. --- ...or_datetime_fm_NTP_touch_and_gVars_test.py | 39 ++++++++++--------- 1 file changed, 20 insertions(+), 19 deletions(-) diff --git a/examples/hotplug_sensor_examples/displayio_layout_tablayout_hotplug_temp_sensor_datetime_fm_NTP_touch_and_gVars_test.py b/examples/hotplug_sensor_examples/displayio_layout_tablayout_hotplug_temp_sensor_datetime_fm_NTP_touch_and_gVars_test.py index 4f8d9b1..a4a3301 100644 --- a/examples/hotplug_sensor_examples/displayio_layout_tablayout_hotplug_temp_sensor_datetime_fm_NTP_touch_and_gVars_test.py +++ b/examples/hotplug_sensor_examples/displayio_layout_tablayout_hotplug_temp_sensor_datetime_fm_NTP_touch_and_gVars_test.py @@ -69,6 +69,7 @@ def __init__(self): 25: "five_min_cnt", 26: "next_NTP_sync_t1", 27: "next_NTP_sync_t3", + 28: "temp_in_fahrenheit", } self.gVars_rDict = { @@ -100,6 +101,7 @@ def __init__(self): "five_min_cnt": 25, "next_NTP_sync_t1": 26, "next_NTP_sync_t3": 27, + "temp_in_fahrenheit": 28, } self.g_vars = {} @@ -161,6 +163,7 @@ def clean(self): 25: None, 26: None, 27: None, + 28: None, } def list(self): @@ -213,6 +216,7 @@ def list(self): myVars.write("five_min_cnt", 0) myVars.write("next_NTP_sync_t1", "Next NTP sync in ") myVars.write("next_NTP_sync_t3", " (mm:ss)") +myVars.write("temp_in_fahrenheit", True) # nHH_old is used to check if the hour has changed. # If so we have to re-sync from NTP server # (if not using an external RTC) @@ -645,17 +649,16 @@ def set_image(group, filename): glyphs = b' "(),-.0123456789:ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz' font_arial.load_glyphs(glyphs) font_arial.load_glyphs(("°",)) # a non-ascii character we need -# gc.collect() # ADDED by @PaulskPt -- to prevent MemoryError - memory allocation failed, +# font=font_term.collect() # ADDED by @PaulskPt -- +# to prevent MemoryError - memory allocation failed, # allocating 6444 bytes pge2_group = 1 -""" - If the temperature sensor has been disconnected, +"""If the temperature sensor has been disconnected, this function will try to reconnect (test if the sensor is present by now) - If reconnected this function creates the temp_sensor object -""" + If reconnected this function creates the temp_sensor object""" def connect_temp_sensor(): @@ -676,7 +679,10 @@ def connect_temp_sensor(): print(t) print("temperature sensor connected") myVars.write("t0", "Temperature") - myVars.write("t1", chr(186) + "C") + if myVars.read("temp_in_fahrenheit"): + myVars.write("t1", chr(186) + "F") + else: + myVars.write("t1", chr(186) + "C") myVars.write("t2", 27 * "_") else: print("no " + t) @@ -686,10 +692,8 @@ def connect_temp_sensor(): myVars.write("t2", None) -""" - If the external rtc has been disconnected, - this function will try to reconnect (test if the external rtc is present by now) -""" +""" If the external rtc has been disconnected, + this function will try to reconnect (test if the external rtc is present by now)""" def connect_rtc(): @@ -715,14 +719,12 @@ def connect_rtc(): print("Failed to connect RTC") -""" - Function gets a value from the external temperature sensor +"""Function gets a value from the external temperature sensor It only updates if the value has changed compared to the previous value A fixed text is set in pge4_lbl2.text. The variable temperature value is set in pge4_lbl3.text If no value obtained (for instance if the sensor is disconnected), the function sets the pge4_lbl to a default text and makes empty - pge4_lbl2.text and pge4_lbl3.text -""" + pge4_lbl2.text and pge4_lbl3.text""" def get_temp(): @@ -732,6 +734,8 @@ def get_temp(): if myVars.read("temp_sensor") is not None: try: temp = myVars.read("temp_sensor").temperature + if myVars.read("temp_in_fahrenheit"): + temp = (temp * 1.8) + 32 t = "{:5.2f}{} ".format(temp, myVars.read("t1")) if my_debug and temp is not None and not myVars.read("temp_in_REPL"): myVars.write("temp_in_REPL", True) @@ -767,7 +771,6 @@ def get_temp(): # Moved these six definitions outside handle_dt() # to correct pylint error 'too many variables' -# dt_idxs = {0: "yy", 1:"mo", 2:"dd", 3:"hh", 4:"mm", 5:"ss"} dt_ridxs = {"yy": 0, "mo": 1, "dd": 2, "hh": 3, "mm": 4, "ss": 5} # print("dict dt_ridxs =", dt_ridxs.keys()) @@ -843,14 +846,12 @@ def handle_dt(dt): return RetVal -""" - Function gets the date and time: +"""Function gets the date and time: a) if an rtc is present from the rtc; b) if using online NTP pool server then get the date and time from the function time.localtime This time.localtime has before been set with data from the NTP server. In both cases the date and time will be set to the pge3_lbl, pge3_lbl12 and pge3_lbl3 - If no (valid) date and time has been received then a default text will be shown on the pge3_lbl -""" + If no (valid) date and time received then a default text will be shown on the pge3_lbl""" def get_dt(): From ceb426bf80e5e6120585801239272667caeaf506 Mon Sep 17 00:00:00 2001 From: "Paulus H.J. Schulinck" Date: Mon, 16 May 2022 14:29:17 +0100 Subject: [PATCH 16/18] first example added flag "temp_in_fahrenheit" As just done with the second example. Added possibility to switch temperature displayed in degrees Celsius or degrees Fahrenheit by setting the gVars flag variable "temp_in_fahrenheit" --- ...layout_hotplug_ext_rtc_temp_sensor_test.py | 36 ++++++++++++------- 1 file changed, 24 insertions(+), 12 deletions(-) diff --git a/examples/hotplug_sensor_examples/displayio_layout_tab_layout_hotplug_ext_rtc_temp_sensor_test.py b/examples/hotplug_sensor_examples/displayio_layout_tab_layout_hotplug_ext_rtc_temp_sensor_test.py index 97dd031..f97d2c6 100644 --- a/examples/hotplug_sensor_examples/displayio_layout_tab_layout_hotplug_ext_rtc_temp_sensor_test.py +++ b/examples/hotplug_sensor_examples/displayio_layout_tab_layout_hotplug_ext_rtc_temp_sensor_test.py @@ -15,6 +15,7 @@ from adafruit_display_shapes.rect import Rect from adafruit_display_shapes.circle import Circle from adafruit_display_shapes.triangle import Triangle +from adafruit_bitmap_font import bitmap_font from adafruit_displayio_layout.layouts.tab_layout import TabLayout # +-------------------------------------------------------+ @@ -49,6 +50,7 @@ def __init__(self): 18: "use_txt_in_month", 19: "use_usa_notation", 20: "content_sensor_idx", + 21: "temp_in_fahrenheit", } self.gVars_rDict = { @@ -73,6 +75,7 @@ def __init__(self): "use_txt_in_month": 18, "use_usa_notation": 19, "content_sensor_idx": 20, + "temp_in_fahrenheit": 21, } self.g_vars = {} @@ -127,6 +130,7 @@ def clean(self): 18: None, 19: None, 20: None, + 21: None, } def list(self): @@ -203,6 +207,7 @@ def list(self): myVars.write("use_usa_notation", True) myVars.write("use_ntp", False) myVars.write("content_sensor_idx", None) +myVars.write("temp_in_fahrenheit", True) # ------------------------------------------------------------------------- if myVars.read("my_debug"): # print list of all variables in myVars @@ -221,7 +226,8 @@ def list(self): display.show(main_group) # fon.gvars bitmap_font.load_font("fonts/Helvetica-Bold-16.bdf") -font = terminalio.FONT +font_arial = bitmap_font.load_font("/fonts/Arial-16.bdf") +font_term = terminalio.FONT # create the page layout test_page_layout = TabLayout( @@ -229,7 +235,7 @@ def list(self): y=0, display=board.DISPLAY, tab_text_scale=2, - custom_font=font, + custom_font=font_term, inactive_tab_spritesheet="bmps/inactive_tab_sprite.bmp", showing_tab_spritesheet="bmps/active_tab_sprite.bmp", showing_tab_text_color=0x00AA59, @@ -247,63 +253,63 @@ def list(self): # labels pge1_lbl = Label( - font=terminalio.FONT, + font=font_term, scale=2, text="This is the first page!", anchor_point=(0, 0), anchored_position=(10, 10), ) pge1_lbl2 = Label( - font=terminalio.FONT, + font=font_term, scale=2, text="Please wait...", anchor_point=(0, 0), anchored_position=(10, 150), ) pge2_lbl = Label( - font=terminalio.FONT, + font=font_term, scale=2, text="This page is the second page!", anchor_point=(0, 0), anchored_position=(10, 10), ) pge3_lbl = Label( - font=terminalio.FONT, + font=font_term, scale=2, text=myVars.read("pge3_lbl_dflt"), # Will be "Date/time:" anchor_point=(0, 0), anchored_position=(10, 10), ) pge3_lbl2 = Label( - font=terminalio.FONT, + font=font_term, scale=2, text="", # pge3_lbl2_dflt, # Will be DD-MO-YYYY or Month-DD-YYYY anchor_point=(0, 0), anchored_position=(10, 40), ) pge3_lbl3 = Label( - font=terminalio.FONT, + font=font_term, scale=2, text="", # pge3_lbl3_dflt, # Will be HH:MM:SS anchor_point=(0, 0), anchored_position=(10, 70), ) pge4_lbl = Label( - font=terminalio.FONT, + font=font_term, scale=2, text=myVars.read("pge4_lbl_dflt"), anchor_point=(0, 0), anchored_position=(10, 10), ) pge4_lbl2 = Label( - font=terminalio.FONT, + font=font_term, scale=2, text="", # Will be "Temperature" anchor_point=(0, 0), anchored_position=(10, 130), ) pge4_lbl3 = Label( - font=terminalio.FONT, + font=font_arial, scale=2, text="", # Will be "xx.yy C" anchor_point=(0, 0), @@ -405,7 +411,11 @@ def connect_temp_sensor(): print(t) print("temperature sensor connected") myVars.write("t0", "Temperature") - myVars.write("t1", " C") + if myVars.read("temp_in_fahrenheit"): + myVars.write("t1", chr(186) + "F") + else: + myVars.write("t1", chr(186) + "C") + myVars.write("t2", 27 * "_") else: print("no " + t) @@ -460,6 +470,8 @@ def get_temp(): if myVars.read("temp_sensor") is not None: try: temp = myVars.read("temp_sensor").temperature + if myVars.read("temp_in_fahrenheit"): + temp = (temp * 1.8) + 32 t = "{:5.2f} ".format(temp) + myVars.read("t1") if ( myVars.read("my_debug") From 65a3d72dd6b2f6979e716be2a37e9bddc0561118 Mon Sep 17 00:00:00 2001 From: "Paulus H.J. Schulinck" Date: Mon, 16 May 2022 14:38:11 +0100 Subject: [PATCH 17/18] example nr 1 changed temp readout to Celsius Now example #1 displays the temperature in degrees Celsius while example #2 displays the temperature in degrees Fahrenheit. --- ...playio_layout_tab_layout_hotplug_ext_rtc_temp_sensor_test.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/hotplug_sensor_examples/displayio_layout_tab_layout_hotplug_ext_rtc_temp_sensor_test.py b/examples/hotplug_sensor_examples/displayio_layout_tab_layout_hotplug_ext_rtc_temp_sensor_test.py index f97d2c6..f56413f 100644 --- a/examples/hotplug_sensor_examples/displayio_layout_tab_layout_hotplug_ext_rtc_temp_sensor_test.py +++ b/examples/hotplug_sensor_examples/displayio_layout_tab_layout_hotplug_ext_rtc_temp_sensor_test.py @@ -207,7 +207,7 @@ def list(self): myVars.write("use_usa_notation", True) myVars.write("use_ntp", False) myVars.write("content_sensor_idx", None) -myVars.write("temp_in_fahrenheit", True) +myVars.write("temp_in_fahrenheit", False) # ------------------------------------------------------------------------- if myVars.read("my_debug"): # print list of all variables in myVars From b495a549698d6b641c6dfc42ef7cf674f82439b0 Mon Sep 17 00:00:00 2001 From: "Paulus H.J. Schulinck" Date: Mon, 16 May 2022 23:32:42 +0100 Subject: [PATCH 18/18] Aded the Arial-16 font Added the Arial-16.bdf font and it's license file --- examples/fonts/Arial-16.bdf | 7366 +++++++++++++++++++++++++++ examples/fonts/Arial-16.bdf.license | 3 + 2 files changed, 7369 insertions(+) create mode 100644 examples/fonts/Arial-16.bdf create mode 100644 examples/fonts/Arial-16.bdf.license diff --git a/examples/fonts/Arial-16.bdf b/examples/fonts/Arial-16.bdf new file mode 100644 index 0000000..087da7d --- /dev/null +++ b/examples/fonts/Arial-16.bdf @@ -0,0 +1,7366 @@ +STARTFONT 2.1 +COMMENT +COMMENT Converted from OpenType font "arial.ttf" by "otf2bdf 3.0". +COMMENT +FONT -FreeType-Arial-Medium-R-Normal--22-160-100-100-P-109-ISO10646-1 +SIZE 16 100 100 +FONTBOUNDINGBOX 43 29 -11 -7 +STARTPROPERTIES 19 +FOUNDRY "FreeType" +FAMILY_NAME "Arial" +WEIGHT_NAME "Medium" +SLANT "R" +SETWIDTH_NAME "Normal" +ADD_STYLE_NAME "" +PIXEL_SIZE 22 +POINT_SIZE 160 +RESOLUTION_X 100 +RESOLUTION_Y 100 +SPACING "P" +AVERAGE_WIDTH 109 +CHARSET_REGISTRY "ISO10646" +CHARSET_ENCODING "1" +FONT_ASCENT 19 +FONT_DESCENT 4 +COPYRIGHT "© 2017 The Monotype Corporation. All Rights Reserved. Hebrew OpenType Layout logic copyright © 2003 & 2007, Ralph Hancock & John Hudson. This layout logic for Biblical Hebrew is open source software under the MIT License; see embedded license description for details." +_OTF_FONTFILE "arial.ttf" +_OTF_PSNAME "ArialMT" +ENDPROPERTIES +CHARS 3361 +STARTCHAR 0020 +ENCODING 32 +SWIDTH 270 0 +DWIDTH 6 0 +BBX 0 0 0 0 +BITMAP +ENDCHAR +STARTCHAR 0021 +ENCODING 33 +SWIDTH 270 0 +DWIDTH 6 0 +BBX 2 16 2 0 +BITMAP +C0 +C0 +C0 +C0 +C0 +C0 +C0 +C0 +C0 +C0 +C0 +C0 +00 +00 +C0 +C0 +ENDCHAR +STARTCHAR 0022 +ENCODING 34 +SWIDTH 360 0 +DWIDTH 8 0 +BBX 6 6 1 10 +BITMAP +CC +CC +CC +CC +CC +CC +ENDCHAR +STARTCHAR 0023 +ENCODING 35 +SWIDTH 540 0 +DWIDTH 12 0 +BBX 12 16 0 0 +BITMAP +0C60 +0C60 +0C60 +18C0 +FFF0 +FFF0 +18C0 +18C0 +3180 +3180 +FFF0 +FFF0 +3180 +6300 +6300 +6300 +ENDCHAR +STARTCHAR 0024 +ENCODING 36 +SWIDTH 540 0 +DWIDTH 12 0 +BBX 10 19 1 -2 +BITMAP +0800 +3E00 +7F80 +E9C0 +C8C0 +C800 +E800 +7800 +3F00 +0F80 +09C0 +08C0 +C8C0 +C8C0 +6980 +7F80 +3E00 +0800 +0800 +ENDCHAR +STARTCHAR 0025 +ENCODING 37 +SWIDTH 900 0 +DWIDTH 20 0 +BBX 18 16 1 0 +BITMAP +380600 +6C0C00 +C60C00 +C61800 +C63000 +C63000 +C66000 +6C6700 +38CD80 +0198C0 +0198C0 +0318C0 +0318C0 +0618C0 +0C0D80 +0C0700 +ENDCHAR +STARTCHAR 0026 +ENCODING 38 +SWIDTH 675 0 +DWIDTH 15 0 +BBX 13 16 1 0 +BITMAP +0E00 +1F00 +3180 +3180 +3180 +1B00 +1F00 +1C00 +7600 +6330 +C1B0 +C1E0 +C0E0 +61A0 +7F98 +1E10 +ENDCHAR +STARTCHAR 0027 +ENCODING 39 +SWIDTH 180 0 +DWIDTH 4 0 +BBX 2 6 1 10 +BITMAP +C0 +C0 +C0 +C0 +C0 +C0 +ENDCHAR +STARTCHAR 0028 +ENCODING 40 +SWIDTH 315 0 +DWIDTH 7 0 +BBX 5 20 1 -4 +BITMAP +08 +10 +30 +20 +60 +60 +C0 +C0 +C0 +C0 +C0 +C0 +C0 +C0 +60 +60 +20 +30 +10 +08 +ENDCHAR +STARTCHAR 0029 +ENCODING 41 +SWIDTH 315 0 +DWIDTH 7 0 +BBX 5 20 1 -4 +BITMAP +80 +40 +60 +20 +30 +30 +18 +18 +18 +18 +18 +18 +18 +18 +30 +30 +20 +60 +40 +80 +ENDCHAR +STARTCHAR 002A +ENCODING 42 +SWIDTH 405 0 +DWIDTH 9 0 +BBX 8 7 1 9 +BITMAP +18 +18 +FF +3C +3C +66 +24 +ENDCHAR +STARTCHAR 002B +ENCODING 43 +SWIDTH 585 0 +DWIDTH 13 0 +BBX 10 10 1 3 +BITMAP +0C00 +0C00 +0C00 +0C00 +FFC0 +FFC0 +0C00 +0C00 +0C00 +0C00 +ENDCHAR +STARTCHAR 002C +ENCODING 44 +SWIDTH 270 0 +DWIDTH 6 0 +BBX 2 5 2 -3 +BITMAP +C0 +C0 +40 +40 +80 +ENDCHAR +STARTCHAR 002D +ENCODING 45 +SWIDTH 315 0 +DWIDTH 7 0 +BBX 6 2 0 5 +BITMAP +FC +FC +ENDCHAR +STARTCHAR 002E +ENCODING 46 +SWIDTH 270 0 +DWIDTH 6 0 +BBX 2 2 2 0 +BITMAP +C0 +C0 +ENDCHAR +STARTCHAR 002F +ENCODING 47 +SWIDTH 270 0 +DWIDTH 6 0 +BBX 7 16 0 0 +BITMAP +06 +06 +0C +0C +0C +18 +18 +18 +30 +30 +30 +60 +60 +60 +E0 +C0 +ENDCHAR +STARTCHAR 0030 +ENCODING 48 +SWIDTH 540 0 +DWIDTH 12 0 +BBX 10 16 1 0 +BITMAP +1E00 +3F80 +6180 +6180 +C0C0 +C0C0 +C0C0 +C0C0 +C0C0 +C0C0 +C0C0 +C0C0 +6180 +6180 +3F00 +1E00 +ENDCHAR +STARTCHAR 0031 +ENCODING 49 +SWIDTH 540 0 +DWIDTH 12 0 +BBX 6 16 2 0 +BITMAP +0C +0C +1C +7C +EC +8C +0C +0C +0C +0C +0C +0C +0C +0C +0C +0C +ENDCHAR +STARTCHAR 0032 +ENCODING 50 +SWIDTH 540 0 +DWIDTH 12 0 +BBX 10 16 1 0 +BITMAP +3F00 +7F80 +E1C0 +C0C0 +00C0 +00C0 +00C0 +0180 +0300 +0600 +0C00 +1800 +3000 +6000 +FFC0 +FFC0 +ENDCHAR +STARTCHAR 0033 +ENCODING 51 +SWIDTH 540 0 +DWIDTH 12 0 +BBX 10 16 1 0 +BITMAP +3E00 +7F00 +E380 +C180 +0180 +0300 +0E00 +0F00 +0180 +00C0 +00C0 +00C0 +C0C0 +E180 +7F80 +3E00 +ENDCHAR +STARTCHAR 0034 +ENCODING 52 +SWIDTH 540 0 +DWIDTH 12 0 +BBX 10 16 1 0 +BITMAP +0300 +0700 +0F00 +0F00 +1B00 +1B00 +3300 +7300 +6300 +C300 +FFC0 +FFC0 +0300 +0300 +0300 +0300 +ENDCHAR +STARTCHAR 0035 +ENCODING 53 +SWIDTH 540 0 +DWIDTH 12 0 +BBX 10 16 1 0 +BITMAP +3F80 +3F80 +6000 +6000 +6000 +7E00 +FF80 +C180 +00C0 +00C0 +00C0 +00C0 +C0C0 +E180 +7F80 +3E00 +ENDCHAR +STARTCHAR 0036 +ENCODING 54 +SWIDTH 540 0 +DWIDTH 12 0 +BBX 10 16 1 0 +BITMAP +1F00 +3F80 +61C0 +60C0 +C000 +C000 +CF00 +FF80 +E1C0 +C0C0 +C0C0 +C0C0 +C0C0 +6180 +7F80 +1E00 +ENDCHAR +STARTCHAR 0037 +ENCODING 55 +SWIDTH 540 0 +DWIDTH 12 0 +BBX 10 16 1 0 +BITMAP +FFC0 +FFC0 +0080 +0180 +0300 +0600 +0600 +0C00 +0C00 +1800 +1800 +1800 +1000 +3000 +3000 +3000 +ENDCHAR +STARTCHAR 0038 +ENCODING 56 +SWIDTH 540 0 +DWIDTH 12 0 +BBX 10 16 1 0 +BITMAP +1E00 +3F00 +6180 +6180 +6180 +6180 +3F00 +3F00 +6180 +C0C0 +C0C0 +C0C0 +C0C0 +6180 +7F80 +1E00 +ENDCHAR +STARTCHAR 0039 +ENCODING 57 +SWIDTH 540 0 +DWIDTH 12 0 +BBX 10 16 1 0 +BITMAP +1E00 +7F00 +6180 +C080 +C0C0 +C0C0 +C0C0 +E1C0 +7FC0 +3CC0 +00C0 +00C0 +C180 +E380 +7F00 +3E00 +ENDCHAR +STARTCHAR 003A +ENCODING 58 +SWIDTH 270 0 +DWIDTH 6 0 +BBX 2 12 2 0 +BITMAP +C0 +C0 +00 +00 +00 +00 +00 +00 +00 +00 +C0 +C0 +ENDCHAR +STARTCHAR 003B +ENCODING 59 +SWIDTH 270 0 +DWIDTH 6 0 +BBX 2 15 2 -3 +BITMAP +C0 +C0 +00 +00 +00 +00 +00 +00 +00 +00 +C0 +C0 +40 +40 +80 +ENDCHAR +STARTCHAR 003C +ENCODING 60 +SWIDTH 585 0 +DWIDTH 13 0 +BBX 11 11 1 2 +BITMAP +0020 +00E0 +07C0 +1E00 +7800 +C000 +7800 +1E00 +07C0 +00E0 +0020 +ENDCHAR +STARTCHAR 003D +ENCODING 61 +SWIDTH 585 0 +DWIDTH 13 0 +BBX 11 7 1 4 +BITMAP +FFE0 +FFE0 +0000 +0000 +0000 +FFE0 +FFE0 +ENDCHAR +STARTCHAR 003E +ENCODING 62 +SWIDTH 585 0 +DWIDTH 13 0 +BBX 11 11 1 2 +BITMAP +8000 +E000 +7C00 +0F00 +03C0 +0060 +03C0 +0F00 +7C00 +E000 +8000 +ENDCHAR +STARTCHAR 003F +ENCODING 63 +SWIDTH 540 0 +DWIDTH 12 0 +BBX 10 16 1 0 +BITMAP +3F00 +7F80 +E1C0 +C0C0 +00C0 +01C0 +0380 +0700 +0600 +0C00 +0C00 +0C00 +0000 +0000 +0C00 +0C00 +ENDCHAR +STARTCHAR 0040 +ENCODING 64 +SWIDTH 990 0 +DWIDTH 22 0 +BBX 20 21 1 -5 +BITMAP +01F800 +07FE00 +1E0780 +180180 +31CCC0 +77ECE0 +6E3860 +6C1860 +DC1860 +D81860 +D81860 +D830C0 +D831C0 +DC7380 +EFFF00 +671C00 +700030 +3800E0 +1E03C0 +0FFF80 +01FC00 +ENDCHAR +STARTCHAR 0041 +ENCODING 65 +SWIDTH 675 0 +DWIDTH 15 0 +BBX 15 16 0 0 +BITMAP +0380 +0380 +06C0 +06C0 +0EE0 +0C60 +0C60 +1830 +1830 +3FF8 +3FF8 +3018 +600C +600C +C006 +C006 +ENDCHAR +STARTCHAR 0042 +ENCODING 66 +SWIDTH 675 0 +DWIDTH 15 0 +BBX 12 16 2 0 +BITMAP +FF80 +FFC0 +C0E0 +C060 +C060 +C060 +C0C0 +FFC0 +FFC0 +C060 +C030 +C030 +C030 +C070 +FFE0 +FF80 +ENDCHAR +STARTCHAR 0043 +ENCODING 67 +SWIDTH 720 0 +DWIDTH 16 0 +BBX 14 16 1 0 +BITMAP +07C0 +1FF0 +3838 +6018 +600C +C000 +C000 +C000 +C000 +C000 +C000 +600C +6018 +3838 +1FF0 +0FC0 +ENDCHAR +STARTCHAR 0044 +ENCODING 68 +SWIDTH 720 0 +DWIDTH 16 0 +BBX 13 16 2 0 +BITMAP +FF80 +FFE0 +C070 +C030 +C038 +C018 +C018 +C018 +C018 +C018 +C018 +C030 +C030 +C0E0 +FFE0 +FF80 +ENDCHAR +STARTCHAR 0045 +ENCODING 69 +SWIDTH 675 0 +DWIDTH 15 0 +BBX 12 16 2 0 +BITMAP +FFF0 +FFF0 +C000 +C000 +C000 +C000 +C000 +FFE0 +FFE0 +C000 +C000 +C000 +C000 +C000 +FFF0 +FFF0 +ENDCHAR +STARTCHAR 0046 +ENCODING 70 +SWIDTH 585 0 +DWIDTH 13 0 +BBX 10 16 2 0 +BITMAP +FFC0 +FFC0 +C000 +C000 +C000 +C000 +C000 +FF80 +FF80 +C000 +C000 +C000 +C000 +C000 +C000 +C000 +ENDCHAR +STARTCHAR 0047 +ENCODING 71 +SWIDTH 765 0 +DWIDTH 17 0 +BBX 15 16 1 0 +BITMAP +07E0 +1FF8 +381C +700C +6006 +C000 +C000 +C000 +C0FE +C0FE +C006 +6006 +7006 +381E +1FFC +07E0 +ENDCHAR +STARTCHAR 0048 +ENCODING 72 +SWIDTH 720 0 +DWIDTH 16 0 +BBX 12 16 2 0 +BITMAP +C030 +C030 +C030 +C030 +C030 +C030 +C030 +FFF0 +FFF0 +C030 +C030 +C030 +C030 +C030 +C030 +C030 +ENDCHAR +STARTCHAR 0049 +ENCODING 73 +SWIDTH 270 0 +DWIDTH 6 0 +BBX 2 16 2 0 +BITMAP +C0 +C0 +C0 +C0 +C0 +C0 +C0 +C0 +C0 +C0 +C0 +C0 +C0 +C0 +C0 +C0 +ENDCHAR +STARTCHAR 004A +ENCODING 74 +SWIDTH 495 0 +DWIDTH 11 0 +BBX 8 16 1 0 +BITMAP +03 +03 +03 +03 +03 +03 +03 +03 +03 +03 +03 +C3 +C3 +E7 +7E +3C +ENDCHAR +STARTCHAR 004B +ENCODING 75 +SWIDTH 675 0 +DWIDTH 15 0 +BBX 13 16 2 0 +BITMAP +C070 +C0E0 +C1C0 +C380 +C700 +CE00 +DC00 +FC00 +FE00 +E700 +C380 +C1C0 +C0C0 +C0E0 +C070 +C038 +ENDCHAR +STARTCHAR 004C +ENCODING 76 +SWIDTH 540 0 +DWIDTH 12 0 +BBX 9 16 2 0 +BITMAP +C000 +C000 +C000 +C000 +C000 +C000 +C000 +C000 +C000 +C000 +C000 +C000 +C000 +C000 +FF80 +FF80 +ENDCHAR +STARTCHAR 004D +ENCODING 77 +SWIDTH 855 0 +DWIDTH 19 0 +BBX 15 16 2 0 +BITMAP +E00E +F01E +F01E +F01E +D836 +D836 +D836 +CC66 +CC66 +CC66 +C6C6 +C6C6 +C6C6 +C386 +C386 +C386 +ENDCHAR +STARTCHAR 004E +ENCODING 78 +SWIDTH 720 0 +DWIDTH 16 0 +BBX 12 16 2 0 +BITMAP +C030 +E030 +F030 +F030 +D830 +D830 +CC30 +C630 +C630 +C330 +C1B0 +C1B0 +C0F0 +C0F0 +C070 +C030 +ENDCHAR +STARTCHAR 004F +ENCODING 79 +SWIDTH 765 0 +DWIDTH 17 0 +BBX 15 16 1 0 +BITMAP +07C0 +1FF0 +3838 +701C +600C +C006 +C006 +C006 +C006 +C006 +C006 +600C +701C +3838 +1FF0 +07C0 +ENDCHAR +STARTCHAR 0050 +ENCODING 80 +SWIDTH 675 0 +DWIDTH 15 0 +BBX 12 16 2 0 +BITMAP +FF80 +FFE0 +C060 +C030 +C030 +C030 +C030 +C060 +FFE0 +FF80 +C000 +C000 +C000 +C000 +C000 +C000 +ENDCHAR +STARTCHAR 0051 +ENCODING 81 +SWIDTH 765 0 +DWIDTH 17 0 +BBX 15 17 1 -1 +BITMAP +07C0 +1FF0 +3838 +701C +600C +C006 +C006 +C006 +C006 +C006 +C006 +600C +70EC +3838 +1FF8 +07EE +0002 +ENDCHAR +STARTCHAR 0052 +ENCODING 82 +SWIDTH 720 0 +DWIDTH 16 0 +BBX 12 16 2 0 +BITMAP +FFC0 +FFE0 +C070 +C030 +C030 +C030 +C070 +FFE0 +FFC0 +C300 +C180 +C1C0 +C0E0 +C060 +C070 +C030 +ENDCHAR +STARTCHAR 0053 +ENCODING 83 +SWIDTH 675 0 +DWIDTH 15 0 +BBX 13 16 1 0 +BITMAP +0FC0 +3FE0 +7070 +6018 +6018 +7000 +3C00 +1FC0 +03F0 +0038 +C018 +C018 +6018 +7070 +3FF0 +0FC0 +ENDCHAR +STARTCHAR 0054 +ENCODING 84 +SWIDTH 630 0 +DWIDTH 14 0 +BBX 12 16 1 0 +BITMAP +FFF0 +FFF0 +0600 +0600 +0600 +0600 +0600 +0600 +0600 +0600 +0600 +0600 +0600 +0600 +0600 +0600 +ENDCHAR +STARTCHAR 0055 +ENCODING 85 +SWIDTH 720 0 +DWIDTH 16 0 +BBX 12 16 2 0 +BITMAP +C030 +C030 +C030 +C030 +C030 +C030 +C030 +C030 +C030 +C030 +C030 +C030 +E070 +70E0 +3FC0 +1F80 +ENDCHAR +STARTCHAR 0056 +ENCODING 86 +SWIDTH 675 0 +DWIDTH 15 0 +BBX 15 16 0 0 +BITMAP +C006 +E00E +600C +600C +3018 +3018 +3838 +1830 +1830 +0C60 +0C60 +0C60 +06C0 +06C0 +07C0 +0380 +ENDCHAR +STARTCHAR 0057 +ENCODING 87 +SWIDTH 945 0 +DWIDTH 21 0 +BBX 21 16 0 0 +BITMAP +C07018 +C07018 +60D830 +60D830 +60D830 +60D830 +318C60 +318C60 +318C60 +318C60 +1B06C0 +1B06C0 +1B06C0 +1B06C0 +0E0380 +0E0380 +ENDCHAR +STARTCHAR 0058 +ENCODING 88 +SWIDTH 675 0 +DWIDTH 15 0 +BBX 15 16 0 0 +BITMAP +701C +3838 +1830 +0C60 +0EE0 +06C0 +0380 +0380 +0380 +06C0 +0C60 +1C70 +1830 +3018 +701C +E00E +ENDCHAR +STARTCHAR 0059 +ENCODING 89 +SWIDTH 630 0 +DWIDTH 14 0 +BBX 14 16 0 0 +BITMAP +E01C +6018 +3030 +3870 +1860 +0CC0 +0FC0 +0780 +0300 +0300 +0300 +0300 +0300 +0300 +0300 +0300 +ENDCHAR +STARTCHAR 005A +ENCODING 90 +SWIDTH 585 0 +DWIDTH 13 0 +BBX 12 16 0 0 +BITMAP +7FF0 +7FF0 +0060 +00C0 +00C0 +0180 +0300 +0600 +0600 +0C00 +1800 +3000 +3000 +6000 +FFF0 +FFF0 +ENDCHAR +STARTCHAR 005B +ENCODING 91 +SWIDTH 270 0 +DWIDTH 6 0 +BBX 4 20 1 -4 +BITMAP +F0 +F0 +C0 +C0 +C0 +C0 +C0 +C0 +C0 +C0 +C0 +C0 +C0 +C0 +C0 +C0 +C0 +C0 +F0 +F0 +ENDCHAR +STARTCHAR 005C +ENCODING 92 +SWIDTH 270 0 +DWIDTH 6 0 +BBX 7 16 0 0 +BITMAP +C0 +C0 +60 +60 +60 +30 +30 +30 +18 +18 +18 +0C +0C +0C +0E +06 +ENDCHAR +STARTCHAR 005D +ENCODING 93 +SWIDTH 270 0 +DWIDTH 6 0 +BBX 4 20 1 -4 +BITMAP +F0 +F0 +30 +30 +30 +30 +30 +30 +30 +30 +30 +30 +30 +30 +30 +30 +30 +30 +F0 +F0 +ENDCHAR +STARTCHAR 005E +ENCODING 94 +SWIDTH 495 0 +DWIDTH 11 0 +BBX 10 9 0 7 +BITMAP +0C00 +1E00 +1E00 +3300 +3300 +3300 +6180 +6180 +C0C0 +ENDCHAR +STARTCHAR 005F +ENCODING 95 +SWIDTH 540 0 +DWIDTH 12 0 +BBX 12 2 0 -4 +BITMAP +FFF0 +FFF0 +ENDCHAR +STARTCHAR 0060 +ENCODING 96 +SWIDTH 315 0 +DWIDTH 7 0 +BBX 3 3 1 13 +BITMAP +C0 +60 +20 +ENDCHAR +STARTCHAR 0061 +ENCODING 97 +SWIDTH 540 0 +DWIDTH 12 0 +BBX 10 12 1 0 +BITMAP +3E00 +7F00 +C180 +C180 +0780 +7F80 +7980 +C180 +C180 +C380 +7F80 +7CC0 +ENDCHAR +STARTCHAR 0062 +ENCODING 98 +SWIDTH 540 0 +DWIDTH 12 0 +BBX 10 16 1 0 +BITMAP +C000 +C000 +C000 +C000 +DE00 +FF80 +E180 +C0C0 +C0C0 +C0C0 +C0C0 +C0C0 +C0C0 +E180 +FF80 +DE00 +ENDCHAR +STARTCHAR 0063 +ENCODING 99 +SWIDTH 495 0 +DWIDTH 11 0 +BBX 9 12 1 0 +BITMAP +1E00 +7F00 +6380 +C180 +C000 +C000 +C000 +C000 +C180 +6380 +7F00 +1E00 +ENDCHAR +STARTCHAR 0064 +ENCODING 100 +SWIDTH 540 0 +DWIDTH 12 0 +BBX 10 16 1 0 +BITMAP +00C0 +00C0 +00C0 +00C0 +1EC0 +7FC0 +61C0 +C0C0 +C0C0 +C0C0 +C0C0 +C0C0 +C0C0 +E1C0 +7FC0 +1EC0 +ENDCHAR +STARTCHAR 0065 +ENCODING 101 +SWIDTH 540 0 +DWIDTH 12 0 +BBX 10 12 1 0 +BITMAP +1E00 +7F80 +6180 +C0C0 +FFC0 +FFC0 +C000 +C000 +E0C0 +7180 +3F80 +1E00 +ENDCHAR +STARTCHAR 0066 +ENCODING 102 +SWIDTH 315 0 +DWIDTH 7 0 +BBX 7 16 0 0 +BITMAP +1E +3E +30 +30 +FC +FC +30 +30 +30 +30 +30 +30 +30 +30 +30 +30 +ENDCHAR +STARTCHAR 0067 +ENCODING 103 +SWIDTH 540 0 +DWIDTH 12 0 +BBX 10 16 1 -4 +BITMAP +1EC0 +7FC0 +61C0 +E0C0 +C0C0 +C0C0 +C0C0 +C0C0 +C1C0 +61C0 +7FC0 +1EC0 +00C0 +C180 +FF80 +3E00 +ENDCHAR +STARTCHAR 0068 +ENCODING 104 +SWIDTH 495 0 +DWIDTH 11 0 +BBX 9 16 1 0 +BITMAP +C000 +C000 +C000 +C000 +DE00 +FF00 +E380 +C180 +C180 +C180 +C180 +C180 +C180 +C180 +C180 +C180 +ENDCHAR +STARTCHAR 0069 +ENCODING 105 +SWIDTH 225 0 +DWIDTH 5 0 +BBX 2 16 1 0 +BITMAP +C0 +C0 +00 +00 +C0 +C0 +C0 +C0 +C0 +C0 +C0 +C0 +C0 +C0 +C0 +C0 +ENDCHAR +STARTCHAR 006A +ENCODING 106 +SWIDTH 180 0 +DWIDTH 4 0 +BBX 4 20 -1 -4 +BITMAP +30 +30 +00 +00 +30 +30 +30 +30 +30 +30 +30 +30 +30 +30 +30 +30 +30 +30 +F0 +E0 +ENDCHAR +STARTCHAR 006B +ENCODING 107 +SWIDTH 450 0 +DWIDTH 10 0 +BBX 9 16 1 0 +BITMAP +C000 +C000 +C000 +C000 +C380 +C700 +CE00 +DC00 +F800 +FC00 +EC00 +CE00 +C600 +C700 +C300 +C380 +ENDCHAR +STARTCHAR 006C +ENCODING 108 +SWIDTH 180 0 +DWIDTH 4 0 +BBX 2 16 1 0 +BITMAP +C0 +C0 +C0 +C0 +C0 +C0 +C0 +C0 +C0 +C0 +C0 +C0 +C0 +C0 +C0 +C0 +ENDCHAR +STARTCHAR 006D +ENCODING 109 +SWIDTH 810 0 +DWIDTH 18 0 +BBX 16 12 1 0 +BITMAP +DE3C +FF7E +E3C7 +C183 +C183 +C183 +C183 +C183 +C183 +C183 +C183 +C183 +ENDCHAR +STARTCHAR 006E +ENCODING 110 +SWIDTH 495 0 +DWIDTH 11 0 +BBX 9 12 1 0 +BITMAP +DE00 +FF00 +E380 +C180 +C180 +C180 +C180 +C180 +C180 +C180 +C180 +C180 +ENDCHAR +STARTCHAR 006F +ENCODING 111 +SWIDTH 585 0 +DWIDTH 13 0 +BBX 11 12 1 0 +BITMAP +1F00 +3F80 +71C0 +E0E0 +C060 +C060 +C060 +C060 +E0E0 +71C0 +3F80 +1F00 +ENDCHAR +STARTCHAR 0070 +ENCODING 112 +SWIDTH 540 0 +DWIDTH 12 0 +BBX 10 16 1 -4 +BITMAP +DE00 +FF80 +E180 +C0C0 +C0C0 +C0C0 +C0C0 +C0C0 +C0C0 +E180 +FF00 +DE00 +C000 +C000 +C000 +C000 +ENDCHAR +STARTCHAR 0071 +ENCODING 113 +SWIDTH 540 0 +DWIDTH 12 0 +BBX 10 16 1 -4 +BITMAP +1EC0 +7FC0 +61C0 +C0C0 +C0C0 +C0C0 +C0C0 +C0C0 +C0C0 +61C0 +7FC0 +1EC0 +00C0 +00C0 +00C0 +00C0 +ENDCHAR +STARTCHAR 0072 +ENCODING 114 +SWIDTH 315 0 +DWIDTH 7 0 +BBX 6 12 1 0 +BITMAP +DC +FC +E0 +C0 +C0 +C0 +C0 +C0 +C0 +C0 +C0 +C0 +ENDCHAR +STARTCHAR 0073 +ENCODING 115 +SWIDTH 495 0 +DWIDTH 11 0 +BBX 9 12 1 0 +BITMAP +3E00 +7F00 +C180 +C000 +F000 +7E00 +1F80 +0380 +0180 +C380 +7F00 +3E00 +ENDCHAR +STARTCHAR 0074 +ENCODING 116 +SWIDTH 270 0 +DWIDTH 6 0 +BBX 5 16 0 0 +BITMAP +20 +60 +60 +60 +F8 +F8 +60 +60 +60 +60 +60 +60 +60 +60 +78 +38 +ENDCHAR +STARTCHAR 0075 +ENCODING 117 +SWIDTH 495 0 +DWIDTH 11 0 +BBX 9 12 1 0 +BITMAP +C180 +C180 +C180 +C180 +C180 +C180 +C180 +C180 +C180 +E380 +7F80 +3D80 +ENDCHAR +STARTCHAR 0076 +ENCODING 118 +SWIDTH 495 0 +DWIDTH 11 0 +BBX 11 12 0 0 +BITMAP +C060 +C060 +60C0 +60C0 +3180 +3180 +3180 +1B00 +1B00 +0E00 +0E00 +0400 +ENDCHAR +STARTCHAR 0077 +ENCODING 119 +SWIDTH 675 0 +DWIDTH 15 0 +BBX 15 12 0 0 +BITMAP +C106 +C386 +C386 +628C +66CC +26C8 +36D8 +36D8 +1450 +1C70 +1C70 +0C60 +ENDCHAR +STARTCHAR 0078 +ENCODING 120 +SWIDTH 450 0 +DWIDTH 10 0 +BBX 10 12 0 0 +BITMAP +E1C0 +6180 +3300 +3300 +1E00 +0C00 +0C00 +1E00 +3300 +3300 +6180 +E1C0 +ENDCHAR +STARTCHAR 0079 +ENCODING 121 +SWIDTH 495 0 +DWIDTH 11 0 +BBX 11 16 0 -4 +BITMAP +C060 +C060 +60C0 +60C0 +30C0 +3180 +1980 +1980 +0F00 +0F00 +0700 +0600 +0E00 +0C00 +7C00 +7800 +ENDCHAR +STARTCHAR 007A +ENCODING 122 +SWIDTH 495 0 +DWIDTH 11 0 +BBX 10 12 0 0 +BITMAP +7FC0 +7FC0 +01C0 +0380 +0700 +0E00 +1C00 +3800 +7000 +E000 +FFC0 +FFC0 +ENDCHAR +STARTCHAR 007B +ENCODING 123 +SWIDTH 315 0 +DWIDTH 7 0 +BBX 6 20 0 -4 +BITMAP +1C +3C +30 +30 +30 +30 +30 +30 +60 +E0 +E0 +60 +30 +30 +30 +30 +30 +30 +3C +1C +ENDCHAR +STARTCHAR 007C +ENCODING 124 +SWIDTH 270 0 +DWIDTH 6 0 +BBX 2 21 2 -5 +BITMAP +C0 +C0 +C0 +C0 +C0 +C0 +C0 +C0 +C0 +C0 +C0 +C0 +C0 +C0 +C0 +C0 +C0 +C0 +C0 +C0 +C0 +ENDCHAR +STARTCHAR 007D +ENCODING 125 +SWIDTH 315 0 +DWIDTH 7 0 +BBX 6 20 1 -4 +BITMAP +E0 +F0 +30 +30 +30 +30 +30 +30 +38 +1C +1C +38 +30 +30 +30 +30 +30 +30 +F0 +E0 +ENDCHAR +STARTCHAR 007E +ENCODING 126 +SWIDTH 585 0 +DWIDTH 13 0 +BBX 11 4 1 6 +BITMAP +7800 +FE20 +8FE0 +03C0 +ENDCHAR +STARTCHAR 00A0 +ENCODING 160 +SWIDTH 270 0 +DWIDTH 6 0 +BBX 0 0 0 0 +BITMAP +ENDCHAR +STARTCHAR 00A1 +ENCODING 161 +SWIDTH 270 0 +DWIDTH 6 0 +BBX 2 16 2 -4 +BITMAP +C0 +C0 +00 +00 +C0 +C0 +C0 +C0 +C0 +C0 +C0 +C0 +C0 +C0 +C0 +C0 +ENDCHAR +STARTCHAR 00A2 +ENCODING 162 +SWIDTH 540 0 +DWIDTH 12 0 +BBX 10 20 1 -4 +BITMAP +0100 +0100 +0100 +0100 +1E00 +3F80 +6380 +E4C0 +C400 +C400 +C800 +C800 +E8C0 +7980 +3F80 +1E00 +1000 +2000 +2000 +2000 +ENDCHAR +STARTCHAR 00A3 +ENCODING 163 +SWIDTH 540 0 +DWIDTH 12 0 +BBX 11 16 0 0 +BITMAP +1F00 +3F80 +71C0 +60C0 +6000 +6000 +6000 +FE00 +FE00 +3000 +3000 +3000 +6000 +7C40 +FFE0 +83C0 +ENDCHAR +STARTCHAR 00A4 +ENCODING 164 +SWIDTH 540 0 +DWIDTH 12 0 +BBX 11 11 1 2 +BITMAP +4040 +EEE0 +7FC0 +3180 +60C0 +60C0 +60C0 +3180 +7FC0 +EEE0 +4040 +ENDCHAR +STARTCHAR 00A5 +ENCODING 165 +SWIDTH 540 0 +DWIDTH 12 0 +BBX 12 16 0 0 +BITMAP +C030 +6060 +6060 +30C0 +30C0 +1980 +1F80 +0F00 +7FE0 +7FE0 +0600 +0600 +7FE0 +7FE0 +0600 +0600 +ENDCHAR +STARTCHAR 00A6 +ENCODING 166 +SWIDTH 270 0 +DWIDTH 6 0 +BBX 2 21 2 -5 +BITMAP +C0 +C0 +C0 +C0 +C0 +C0 +C0 +C0 +00 +00 +00 +00 +C0 +C0 +C0 +C0 +C0 +C0 +C0 +C0 +C0 +ENDCHAR +STARTCHAR 00A7 +ENCODING 167 +SWIDTH 540 0 +DWIDTH 12 0 +BBX 10 20 1 -4 +BITMAP +1E00 +3F00 +7380 +6180 +6000 +3800 +7C00 +CE00 +C380 +C1C0 +E0C0 +70C0 +1D80 +0F00 +0700 +0180 +6180 +7180 +3F00 +1E00 +ENDCHAR +STARTCHAR 00A8 +ENCODING 168 +SWIDTH 315 0 +DWIDTH 7 0 +BBX 6 2 1 14 +BITMAP +CC +CC +ENDCHAR +STARTCHAR 00A9 +ENCODING 169 +SWIDTH 720 0 +DWIDTH 16 0 +BBX 16 16 0 0 +BITMAP +07E0 +1818 +2004 +43C2 +4422 +8811 +8801 +8801 +8801 +8801 +8811 +4422 +43C2 +2004 +1818 +07E0 +ENDCHAR +STARTCHAR 00AA +ENCODING 170 +SWIDTH 360 0 +DWIDTH 8 0 +BBX 7 8 0 8 +BITMAP +7C +C6 +06 +3E +F6 +C6 +CE +76 +ENDCHAR +STARTCHAR 00AB +ENCODING 171 +SWIDTH 540 0 +DWIDTH 12 0 +BBX 9 10 1 1 +BITMAP +1980 +3300 +7700 +6600 +CC00 +CC00 +6600 +7700 +3300 +1980 +ENDCHAR +STARTCHAR 00AC +ENCODING 172 +SWIDTH 585 0 +DWIDTH 13 0 +BBX 11 6 1 5 +BITMAP +FFE0 +FFE0 +0060 +0060 +0060 +0060 +ENDCHAR +STARTCHAR 00AD +ENCODING 173 +SWIDTH 315 0 +DWIDTH 7 0 +BBX 6 2 0 5 +BITMAP +FC +FC +ENDCHAR +STARTCHAR 00AE +ENCODING 174 +SWIDTH 720 0 +DWIDTH 16 0 +BBX 16 16 0 0 +BITMAP +07E0 +1818 +2004 +47C2 +4422 +8421 +8421 +87C1 +8481 +8441 +8421 +4422 +4412 +2004 +1818 +07E0 +ENDCHAR +STARTCHAR 00AF +ENCODING 175 +SWIDTH 540 0 +DWIDTH 12 0 +BBX 13 2 -1 17 +BITMAP +FFF8 +FFF8 +ENDCHAR +STARTCHAR 00B0 +ENCODING 176 +SWIDTH 405 0 +DWIDTH 9 0 +BBX 6 6 1 10 +BITMAP +78 +CC +84 +84 +CC +78 +ENDCHAR +STARTCHAR 00B1 +ENCODING 177 +SWIDTH 540 0 +DWIDTH 12 0 +BBX 10 13 1 0 +BITMAP +0C00 +0C00 +0C00 +0C00 +FFC0 +FFC0 +0C00 +0C00 +0C00 +0C00 +0000 +FFC0 +FFC0 +ENDCHAR +STARTCHAR 00B2 +ENCODING 178 +SWIDTH 315 0 +DWIDTH 7 0 +BBX 7 8 0 8 +BITMAP +7C +C6 +06 +0E +1C +38 +60 +FE +ENDCHAR +STARTCHAR 00B3 +ENCODING 179 +SWIDTH 315 0 +DWIDTH 7 0 +BBX 7 8 0 8 +BITMAP +7C +C6 +06 +18 +06 +06 +C6 +7C +ENDCHAR +STARTCHAR 00B4 +ENCODING 180 +SWIDTH 315 0 +DWIDTH 7 0 +BBX 3 3 2 13 +BITMAP +60 +C0 +80 +ENDCHAR +STARTCHAR 00B5 +ENCODING 181 +SWIDTH 540 0 +DWIDTH 12 0 +BBX 10 16 1 -4 +BITMAP +C0C0 +C0C0 +C0C0 +C0C0 +C0C0 +C0C0 +C0C0 +C0C0 +C0C0 +E1C0 +FFC0 +DEC0 +C000 +C000 +C000 +C000 +ENDCHAR +STARTCHAR 00B6 +ENCODING 182 +SWIDTH 540 0 +DWIDTH 12 0 +BBX 12 20 0 -4 +BITMAP +3FF0 +7FF0 +FC60 +FC60 +FC60 +FC60 +FC60 +7C60 +3C60 +0C60 +0C60 +0C60 +0C60 +0C60 +0C60 +0C60 +0C60 +0C60 +0C60 +0C60 +ENDCHAR +STARTCHAR 00B7 +ENCODING 183 +SWIDTH 315 0 +DWIDTH 7 0 +BBX 2 2 3 7 +BITMAP +C0 +C0 +ENDCHAR +STARTCHAR 00B8 +ENCODING 184 +SWIDTH 315 0 +DWIDTH 7 0 +BBX 5 4 1 -4 +BITMAP +20 +30 +18 +F0 +ENDCHAR +STARTCHAR 00B9 +ENCODING 185 +SWIDTH 315 0 +DWIDTH 7 0 +BBX 4 8 1 8 +BITMAP +30 +70 +F0 +B0 +30 +30 +30 +30 +ENDCHAR +STARTCHAR 00BA +ENCODING 186 +SWIDTH 360 0 +DWIDTH 8 0 +BBX 8 8 0 8 +BITMAP +3C +66 +C3 +C3 +C3 +C3 +66 +3C +ENDCHAR +STARTCHAR 00BB +ENCODING 187 +SWIDTH 540 0 +DWIDTH 12 0 +BBX 9 10 2 1 +BITMAP +CC00 +6600 +7700 +3300 +1980 +1980 +3300 +7700 +6600 +CC00 +ENDCHAR +STARTCHAR 00BC +ENCODING 188 +SWIDTH 810 0 +DWIDTH 18 0 +BBX 16 16 2 0 +BITMAP +300C +7018 +F030 +B060 +3060 +30C0 +3180 +3300 +0306 +060E +0C1E +0C36 +1866 +307F +6006 +6006 +ENDCHAR +STARTCHAR 00BD +ENCODING 189 +SWIDTH 810 0 +DWIDTH 18 0 +BBX 16 16 2 0 +BITMAP +300C +7018 +F030 +B060 +3060 +30C0 +3180 +3180 +031E +0633 +0C03 +0C07 +1806 +300C +7018 +603F +ENDCHAR +STARTCHAR 00BE +ENCODING 190 +SWIDTH 810 0 +DWIDTH 18 0 +BBX 17 16 0 0 +BITMAP +7C0300 +C60600 +060C00 +180C00 +061800 +063000 +C63000 +7C6000 +00C300 +018700 +018F00 +031B00 +063300 +0C3F80 +0C0300 +180300 +ENDCHAR +STARTCHAR 00BF +ENCODING 191 +SWIDTH 585 0 +DWIDTH 13 0 +BBX 9 16 2 -4 +BITMAP +0C00 +0C00 +0000 +0000 +0C00 +0C00 +0C00 +1800 +3800 +7000 +E000 +C000 +C180 +E380 +7F00 +3E00 +ENDCHAR +STARTCHAR 00C0 +ENCODING 192 +SWIDTH 675 0 +DWIDTH 15 0 +BBX 15 20 0 0 +BITMAP +0300 +0180 +0080 +0000 +0380 +0380 +06C0 +06C0 +0EE0 +0C60 +0C60 +1830 +1830 +3FF8 +3FF8 +3018 +600C +600C +C006 +C006 +ENDCHAR +STARTCHAR 00C1 +ENCODING 193 +SWIDTH 675 0 +DWIDTH 15 0 +BBX 15 20 0 0 +BITMAP +0180 +0300 +0200 +0000 +0380 +0380 +06C0 +06C0 +0EE0 +0C60 +0C60 +1830 +1830 +3FF8 +3FF8 +3018 +600C +600C +C006 +C006 +ENDCHAR +STARTCHAR 00C2 +ENCODING 194 +SWIDTH 675 0 +DWIDTH 15 0 +BBX 15 20 0 0 +BITMAP +0180 +03C0 +0660 +0000 +0380 +0380 +06C0 +06C0 +0EE0 +0C60 +0C60 +1830 +1830 +3FF8 +3FF8 +3018 +600C +600C +C006 +C006 +ENDCHAR +STARTCHAR 00C3 +ENCODING 195 +SWIDTH 675 0 +DWIDTH 15 0 +BBX 15 20 0 0 +BITMAP +0760 +0FE0 +0DC0 +0000 +0380 +0380 +06C0 +06C0 +0EE0 +0C60 +0C60 +1830 +1830 +3FF8 +3FF8 +3018 +600C +600C +C006 +C006 +ENDCHAR +STARTCHAR 00C4 +ENCODING 196 +SWIDTH 675 0 +DWIDTH 15 0 +BBX 15 19 0 0 +BITMAP +0660 +0660 +0000 +0380 +0380 +06C0 +06C0 +0EE0 +0C60 +0C60 +1830 +1830 +3FF8 +3FF8 +3018 +600C +600C +C006 +C006 +ENDCHAR +STARTCHAR 00C5 +ENCODING 197 +SWIDTH 675 0 +DWIDTH 15 0 +BBX 15 20 0 0 +BITMAP +0380 +0440 +0440 +0440 +0380 +0380 +06C0 +06C0 +0EE0 +0C60 +0C60 +1830 +1830 +3FF8 +3FF8 +3018 +600C +600C +C006 +C006 +ENDCHAR +STARTCHAR 00C6 +ENCODING 198 +SWIDTH 990 0 +DWIDTH 22 0 +BBX 21 16 0 0 +BITMAP +00FFF8 +01FFF8 +019800 +031800 +061800 +061800 +0C1800 +0C1FF0 +181FF0 +1FF800 +3FF800 +301800 +601800 +601800 +C01FF8 +C01FF8 +ENDCHAR +STARTCHAR 00C7 +ENCODING 199 +SWIDTH 720 0 +DWIDTH 16 0 +BBX 14 20 1 -4 +BITMAP +07C0 +1FF0 +3838 +6018 +600C +C000 +C000 +C000 +C000 +C000 +C000 +600C +6018 +3838 +1FF0 +0FC0 +0200 +0300 +0180 +0F00 +ENDCHAR +STARTCHAR 00C8 +ENCODING 200 +SWIDTH 675 0 +DWIDTH 15 0 +BBX 12 20 2 0 +BITMAP +0C00 +0600 +0200 +0000 +FFF0 +FFF0 +C000 +C000 +C000 +C000 +C000 +FFE0 +FFE0 +C000 +C000 +C000 +C000 +C000 +FFF0 +FFF0 +ENDCHAR +STARTCHAR 00C9 +ENCODING 201 +SWIDTH 675 0 +DWIDTH 15 0 +BBX 12 20 2 0 +BITMAP +0300 +0600 +0400 +0000 +FFF0 +FFF0 +C000 +C000 +C000 +C000 +C000 +FFE0 +FFE0 +C000 +C000 +C000 +C000 +C000 +FFF0 +FFF0 +ENDCHAR +STARTCHAR 00CA +ENCODING 202 +SWIDTH 675 0 +DWIDTH 15 0 +BBX 12 20 2 0 +BITMAP +0600 +0F00 +1980 +0000 +FFF0 +FFF0 +C000 +C000 +C000 +C000 +C000 +FFE0 +FFE0 +C000 +C000 +C000 +C000 +C000 +FFF0 +FFF0 +ENDCHAR +STARTCHAR 00CB +ENCODING 203 +SWIDTH 675 0 +DWIDTH 15 0 +BBX 12 19 2 0 +BITMAP +1980 +1980 +0000 +FFF0 +FFF0 +C000 +C000 +C000 +C000 +C000 +FFE0 +FFE0 +C000 +C000 +C000 +C000 +C000 +FFF0 +FFF0 +ENDCHAR +STARTCHAR 00CC +ENCODING 204 +SWIDTH 270 0 +DWIDTH 6 0 +BBX 3 20 1 0 +BITMAP +C0 +60 +20 +00 +60 +60 +60 +60 +60 +60 +60 +60 +60 +60 +60 +60 +60 +60 +60 +60 +ENDCHAR +STARTCHAR 00CD +ENCODING 205 +SWIDTH 270 0 +DWIDTH 6 0 +BBX 3 20 2 0 +BITMAP +60 +C0 +80 +00 +C0 +C0 +C0 +C0 +C0 +C0 +C0 +C0 +C0 +C0 +C0 +C0 +C0 +C0 +C0 +C0 +ENDCHAR +STARTCHAR 00CE +ENCODING 206 +SWIDTH 270 0 +DWIDTH 6 0 +BBX 6 20 0 0 +BITMAP +30 +78 +CC +00 +30 +30 +30 +30 +30 +30 +30 +30 +30 +30 +30 +30 +30 +30 +30 +30 +ENDCHAR +STARTCHAR 00CF +ENCODING 207 +SWIDTH 270 0 +DWIDTH 6 0 +BBX 6 19 0 0 +BITMAP +CC +CC +00 +30 +30 +30 +30 +30 +30 +30 +30 +30 +30 +30 +30 +30 +30 +30 +30 +ENDCHAR +STARTCHAR 00D0 +ENCODING 208 +SWIDTH 720 0 +DWIDTH 16 0 +BBX 15 16 0 0 +BITMAP +3FE0 +3FF8 +301C +300C +300E +3006 +3006 +FF06 +FF06 +3006 +3006 +300C +300C +303C +3FF8 +3FE0 +ENDCHAR +STARTCHAR 00D1 +ENCODING 209 +SWIDTH 720 0 +DWIDTH 16 0 +BBX 12 20 2 0 +BITMAP +0EC0 +1FC0 +1B80 +0000 +C030 +E030 +F030 +F030 +D830 +D830 +CC30 +C630 +C630 +C330 +C1B0 +C1B0 +C0F0 +C0F0 +C070 +C030 +ENDCHAR +STARTCHAR 00D2 +ENCODING 210 +SWIDTH 765 0 +DWIDTH 17 0 +BBX 15 20 1 0 +BITMAP +0300 +0180 +0080 +0000 +07C0 +1FF0 +3838 +701C +600C +C006 +C006 +C006 +C006 +C006 +C006 +600C +701C +3838 +1FF0 +07C0 +ENDCHAR +STARTCHAR 00D3 +ENCODING 211 +SWIDTH 765 0 +DWIDTH 17 0 +BBX 15 20 1 0 +BITMAP +0180 +0300 +0200 +0000 +07C0 +1FF0 +3838 +701C +600C +C006 +C006 +C006 +C006 +C006 +C006 +600C +701C +3838 +1FF0 +07C0 +ENDCHAR +STARTCHAR 00D4 +ENCODING 212 +SWIDTH 765 0 +DWIDTH 17 0 +BBX 15 20 1 0 +BITMAP +0180 +03C0 +0660 +0000 +07C0 +1FF0 +3838 +701C +600C +C006 +C006 +C006 +C006 +C006 +C006 +600C +701C +3838 +1FF0 +07C0 +ENDCHAR +STARTCHAR 00D5 +ENCODING 213 +SWIDTH 765 0 +DWIDTH 17 0 +BBX 15 20 1 0 +BITMAP +0760 +0FE0 +0DC0 +0000 +07C0 +1FF0 +3838 +701C +600C +C006 +C006 +C006 +C006 +C006 +C006 +600C +701C +3838 +1FF0 +07C0 +ENDCHAR +STARTCHAR 00D6 +ENCODING 214 +SWIDTH 765 0 +DWIDTH 17 0 +BBX 15 19 1 0 +BITMAP +0660 +0660 +0000 +07C0 +1FF0 +3838 +701C +600C +C006 +C006 +C006 +C006 +C006 +C006 +600C +701C +3838 +1FF0 +07C0 +ENDCHAR +STARTCHAR 00D7 +ENCODING 215 +SWIDTH 585 0 +DWIDTH 13 0 +BBX 9 9 2 3 +BITMAP +8100 +E380 +7700 +3E00 +1C00 +3E00 +7700 +E380 +8100 +ENDCHAR +STARTCHAR 00D8 +ENCODING 216 +SWIDTH 765 0 +DWIDTH 17 0 +BBX 15 16 1 -1 +BITMAP +07C6 +1FFC +383C +701C +603C +C066 +C0C6 +C186 +C306 +C606 +C606 +6C0C +781C +3838 +7FF0 +CFC0 +ENDCHAR +STARTCHAR 00D9 +ENCODING 217 +SWIDTH 720 0 +DWIDTH 16 0 +BBX 12 20 2 0 +BITMAP +0C00 +0600 +0200 +0000 +C030 +C030 +C030 +C030 +C030 +C030 +C030 +C030 +C030 +C030 +C030 +C030 +E070 +70E0 +3FC0 +1F80 +ENDCHAR +STARTCHAR 00DA +ENCODING 218 +SWIDTH 720 0 +DWIDTH 16 0 +BBX 12 20 2 0 +BITMAP +0300 +0600 +0400 +0000 +C030 +C030 +C030 +C030 +C030 +C030 +C030 +C030 +C030 +C030 +C030 +C030 +E070 +70E0 +3FC0 +1F80 +ENDCHAR +STARTCHAR 00DB +ENCODING 219 +SWIDTH 720 0 +DWIDTH 16 0 +BBX 12 20 2 0 +BITMAP +0600 +0F00 +1980 +0000 +C030 +C030 +C030 +C030 +C030 +C030 +C030 +C030 +C030 +C030 +C030 +C030 +E070 +70E0 +3FC0 +1F80 +ENDCHAR +STARTCHAR 00DC +ENCODING 220 +SWIDTH 720 0 +DWIDTH 16 0 +BBX 12 19 2 0 +BITMAP +1980 +1980 +0000 +C030 +C030 +C030 +C030 +C030 +C030 +C030 +C030 +C030 +C030 +C030 +C030 +E070 +70E0 +3FC0 +1F80 +ENDCHAR +STARTCHAR 00DD +ENCODING 221 +SWIDTH 630 0 +DWIDTH 14 0 +BBX 14 20 0 0 +BITMAP +0180 +0300 +0200 +0000 +E01C +6018 +3030 +3870 +1860 +0CC0 +0FC0 +0780 +0300 +0300 +0300 +0300 +0300 +0300 +0300 +0300 +ENDCHAR +STARTCHAR 00DE +ENCODING 222 +SWIDTH 675 0 +DWIDTH 15 0 +BBX 12 16 2 0 +BITMAP +C000 +C000 +C000 +FF80 +FFE0 +C060 +C030 +C030 +C030 +C030 +C060 +FFE0 +FF80 +C000 +C000 +C000 +ENDCHAR +STARTCHAR 00DF +ENCODING 223 +SWIDTH 585 0 +DWIDTH 13 0 +BBX 11 16 2 0 +BITMAP +3E00 +7F00 +E380 +C180 +C180 +C300 +C700 +C600 +C700 +C380 +C0C0 +C060 +C060 +DCE0 +CFC0 +C780 +ENDCHAR +STARTCHAR 00E0 +ENCODING 224 +SWIDTH 540 0 +DWIDTH 12 0 +BBX 10 16 1 0 +BITMAP +1800 +0C00 +0400 +0000 +3E00 +7F00 +C180 +C180 +0780 +7F80 +7980 +C180 +C180 +C380 +7F80 +7CC0 +ENDCHAR +STARTCHAR 00E1 +ENCODING 225 +SWIDTH 540 0 +DWIDTH 12 0 +BBX 10 16 1 0 +BITMAP +0600 +0C00 +0800 +0000 +3E00 +7F00 +C180 +C180 +0780 +7F80 +7980 +C180 +C180 +C380 +7F80 +7CC0 +ENDCHAR +STARTCHAR 00E2 +ENCODING 226 +SWIDTH 540 0 +DWIDTH 12 0 +BBX 10 16 1 0 +BITMAP +0C00 +1E00 +3300 +0000 +3E00 +7F00 +C180 +C180 +0780 +7F80 +7980 +C180 +C180 +C380 +7F80 +7CC0 +ENDCHAR +STARTCHAR 00E3 +ENCODING 227 +SWIDTH 540 0 +DWIDTH 12 0 +BBX 10 16 1 0 +BITMAP +3B00 +7F00 +6E00 +0000 +3E00 +7F00 +C180 +C180 +0780 +7F80 +7980 +C180 +C180 +C380 +7F80 +7CC0 +ENDCHAR +STARTCHAR 00E4 +ENCODING 228 +SWIDTH 540 0 +DWIDTH 12 0 +BBX 10 15 1 0 +BITMAP +3300 +3300 +0000 +3E00 +7F00 +C180 +C180 +0780 +7F80 +7980 +C180 +C180 +C380 +7F80 +7CC0 +ENDCHAR +STARTCHAR 00E5 +ENCODING 229 +SWIDTH 540 0 +DWIDTH 12 0 +BBX 10 18 1 0 +BITMAP +1C00 +2200 +2200 +2200 +1C00 +0000 +3E00 +7F00 +C180 +C180 +0780 +7F80 +7980 +C180 +C180 +C380 +7F80 +7CC0 +ENDCHAR +STARTCHAR 00E6 +ENCODING 230 +SWIDTH 900 0 +DWIDTH 20 0 +BBX 18 12 1 0 +BITMAP +3F3E00 +7FFF80 +E0E180 +C0C0C0 +03FFC0 +3FFFC0 +7CC000 +C0C000 +C0C0C0 +E1E180 +7F7F80 +3C1E00 +ENDCHAR +STARTCHAR 00E7 +ENCODING 231 +SWIDTH 495 0 +DWIDTH 11 0 +BBX 9 16 1 -4 +BITMAP +1E00 +7F00 +6380 +C180 +C000 +C000 +C000 +C000 +C180 +6380 +7F00 +1E00 +0800 +0C00 +0600 +3C00 +ENDCHAR +STARTCHAR 00E8 +ENCODING 232 +SWIDTH 540 0 +DWIDTH 12 0 +BBX 10 16 1 0 +BITMAP +1800 +0C00 +0400 +0000 +1E00 +7F80 +6180 +C0C0 +FFC0 +FFC0 +C000 +C000 +E0C0 +7180 +3F80 +1E00 +ENDCHAR +STARTCHAR 00E9 +ENCODING 233 +SWIDTH 540 0 +DWIDTH 12 0 +BBX 10 16 1 0 +BITMAP +0600 +0C00 +0800 +0000 +1E00 +7F80 +6180 +C0C0 +FFC0 +FFC0 +C000 +C000 +E0C0 +7180 +3F80 +1E00 +ENDCHAR +STARTCHAR 00EA +ENCODING 234 +SWIDTH 540 0 +DWIDTH 12 0 +BBX 10 16 1 0 +BITMAP +0C00 +1E00 +3300 +0000 +1E00 +7F80 +6180 +C0C0 +FFC0 +FFC0 +C000 +C000 +E0C0 +7180 +3F80 +1E00 +ENDCHAR +STARTCHAR 00EB +ENCODING 235 +SWIDTH 540 0 +DWIDTH 12 0 +BBX 10 15 1 0 +BITMAP +3300 +3300 +0000 +1E00 +7F80 +6180 +C0C0 +FFC0 +FFC0 +C000 +C000 +E0C0 +7180 +3F80 +1E00 +ENDCHAR +STARTCHAR 00EC +ENCODING 236 +SWIDTH 270 0 +DWIDTH 6 0 +BBX 3 16 1 0 +BITMAP +C0 +60 +20 +00 +60 +60 +60 +60 +60 +60 +60 +60 +60 +60 +60 +60 +ENDCHAR +STARTCHAR 00ED +ENCODING 237 +SWIDTH 270 0 +DWIDTH 6 0 +BBX 3 16 2 0 +BITMAP +60 +C0 +80 +00 +C0 +C0 +C0 +C0 +C0 +C0 +C0 +C0 +C0 +C0 +C0 +C0 +ENDCHAR +STARTCHAR 00EE +ENCODING 238 +SWIDTH 270 0 +DWIDTH 6 0 +BBX 6 16 0 0 +BITMAP +30 +78 +CC +00 +30 +30 +30 +30 +30 +30 +30 +30 +30 +30 +30 +30 +ENDCHAR +STARTCHAR 00EF +ENCODING 239 +SWIDTH 270 0 +DWIDTH 6 0 +BBX 6 15 0 0 +BITMAP +CC +CC +00 +30 +30 +30 +30 +30 +30 +30 +30 +30 +30 +30 +30 +ENDCHAR +STARTCHAR 00F0 +ENCODING 240 +SWIDTH 540 0 +DWIDTH 12 0 +BBX 10 16 1 0 +BITMAP +1900 +0F00 +1E00 +3300 +1D00 +7F80 +6180 +E1C0 +C0C0 +C0C0 +C0C0 +C0C0 +C1C0 +6180 +7F80 +1E00 +ENDCHAR +STARTCHAR 00F1 +ENCODING 241 +SWIDTH 495 0 +DWIDTH 11 0 +BBX 9 16 1 0 +BITMAP +3B00 +7F00 +6E00 +0000 +DE00 +FF00 +E380 +C180 +C180 +C180 +C180 +C180 +C180 +C180 +C180 +C180 +ENDCHAR +STARTCHAR 00F2 +ENCODING 242 +SWIDTH 585 0 +DWIDTH 13 0 +BBX 11 16 1 0 +BITMAP +0C00 +0600 +0200 +0000 +1F00 +3F80 +71C0 +E0E0 +C060 +C060 +C060 +C060 +E0E0 +71C0 +3F80 +1F00 +ENDCHAR +STARTCHAR 00F3 +ENCODING 243 +SWIDTH 585 0 +DWIDTH 13 0 +BBX 11 16 1 0 +BITMAP +0300 +0600 +0400 +0000 +1F00 +3F80 +71C0 +E0E0 +C060 +C060 +C060 +C060 +E0E0 +71C0 +3F80 +1F00 +ENDCHAR +STARTCHAR 00F4 +ENCODING 244 +SWIDTH 585 0 +DWIDTH 13 0 +BBX 11 16 1 0 +BITMAP +0600 +0F00 +1980 +0000 +1F00 +3F80 +71C0 +E0E0 +C060 +C060 +C060 +C060 +E0E0 +71C0 +3F80 +1F00 +ENDCHAR +STARTCHAR 00F5 +ENCODING 245 +SWIDTH 585 0 +DWIDTH 13 0 +BBX 11 16 1 0 +BITMAP +1D80 +3F80 +3700 +0000 +1F00 +3F80 +71C0 +E0E0 +C060 +C060 +C060 +C060 +E0E0 +71C0 +3F80 +1F00 +ENDCHAR +STARTCHAR 00F6 +ENCODING 246 +SWIDTH 585 0 +DWIDTH 13 0 +BBX 11 15 1 0 +BITMAP +1980 +1980 +0000 +1F00 +3F80 +71C0 +E0E0 +C060 +C060 +C060 +C060 +E0E0 +71C0 +3F80 +1F00 +ENDCHAR +STARTCHAR 00F7 +ENCODING 247 +SWIDTH 540 0 +DWIDTH 12 0 +BBX 10 8 1 4 +BITMAP +0C00 +0C00 +0000 +FFC0 +FFC0 +0000 +0C00 +0C00 +ENDCHAR +STARTCHAR 00F8 +ENCODING 248 +SWIDTH 630 0 +DWIDTH 14 0 +BBX 11 14 1 -1 +BITMAP +0060 +1F60 +7FC0 +71C0 +E3E0 +C660 +C660 +CC60 +D860 +F8E0 +71C0 +7F80 +DF00 +4000 +ENDCHAR +STARTCHAR 00F9 +ENCODING 249 +SWIDTH 495 0 +DWIDTH 11 0 +BBX 9 16 1 0 +BITMAP +3000 +1800 +0800 +0000 +C180 +C180 +C180 +C180 +C180 +C180 +C180 +C180 +C180 +E380 +7F80 +3D80 +ENDCHAR +STARTCHAR 00FA +ENCODING 250 +SWIDTH 495 0 +DWIDTH 11 0 +BBX 9 16 1 0 +BITMAP +0600 +0C00 +0800 +0000 +C180 +C180 +C180 +C180 +C180 +C180 +C180 +C180 +C180 +E380 +7F80 +3D80 +ENDCHAR +STARTCHAR 00FB +ENCODING 251 +SWIDTH 495 0 +DWIDTH 11 0 +BBX 9 16 1 0 +BITMAP +0C00 +1E00 +3300 +0000 +C180 +C180 +C180 +C180 +C180 +C180 +C180 +C180 +C180 +E380 +7F80 +3D80 +ENDCHAR +STARTCHAR 00FC +ENCODING 252 +SWIDTH 495 0 +DWIDTH 11 0 +BBX 9 15 1 0 +BITMAP +6600 +6600 +0000 +C180 +C180 +C180 +C180 +C180 +C180 +C180 +C180 +C180 +E380 +7F80 +3D80 +ENDCHAR +STARTCHAR 00FD +ENCODING 253 +SWIDTH 495 0 +DWIDTH 11 0 +BBX 11 20 0 -4 +BITMAP +0300 +0600 +0400 +0000 +C060 +C060 +60C0 +60C0 +30C0 +3180 +1980 +1980 +0F00 +0F00 +0700 +0600 +0E00 +0C00 +7C00 +7800 +ENDCHAR +STARTCHAR 00FE +ENCODING 254 +SWIDTH 540 0 +DWIDTH 12 0 +BBX 10 20 1 -4 +BITMAP +C000 +C000 +C000 +C000 +DE00 +FF80 +E180 +C1C0 +C0C0 +C0C0 +C0C0 +C0C0 +C1C0 +E180 +FF00 +DE00 +C000 +C000 +C000 +C000 +ENDCHAR +STARTCHAR 00FF +ENCODING 255 +SWIDTH 495 0 +DWIDTH 11 0 +BBX 11 19 0 -4 +BITMAP +1980 +1980 +0000 +C060 +C060 +60C0 +60C0 +30C0 +3180 +1980 +1980 +0F00 +0F00 +0700 +0600 +0E00 +0C00 +7C00 +7800 +ENDCHAR +STARTCHAR 0100 +ENCODING 256 +SWIDTH 675 0 +DWIDTH 15 0 +BBX 15 19 0 0 +BITMAP +07E0 +07E0 +0000 +0380 +0380 +06C0 +06C0 +0EE0 +0C60 +0C60 +1830 +1830 +3FF8 +3FF8 +3018 +600C +600C +C006 +C006 +ENDCHAR +STARTCHAR 0101 +ENCODING 257 +SWIDTH 540 0 +DWIDTH 12 0 +BBX 10 15 1 0 +BITMAP +3F00 +3F00 +0000 +3E00 +7F00 +C180 +C180 +0780 +7F80 +7980 +C180 +C180 +C380 +7F80 +7CC0 +ENDCHAR +STARTCHAR 0102 +ENCODING 258 +SWIDTH 675 0 +DWIDTH 15 0 +BBX 15 20 0 0 +BITMAP +0820 +0C60 +07C0 +0000 +0380 +0380 +06C0 +06C0 +0EE0 +0C60 +0C60 +1830 +1830 +3FF8 +3FF8 +3018 +600C +600C +C006 +C006 +ENDCHAR +STARTCHAR 0103 +ENCODING 259 +SWIDTH 540 0 +DWIDTH 12 0 +BBX 10 16 1 0 +BITMAP +4100 +6300 +3E00 +0000 +3E00 +7F00 +C180 +C180 +0780 +7F80 +7980 +C180 +C180 +C380 +7F80 +7CC0 +ENDCHAR +STARTCHAR 0104 +ENCODING 260 +SWIDTH 675 0 +DWIDTH 15 0 +BBX 15 20 0 -4 +BITMAP +0380 +0380 +06C0 +06C0 +0EE0 +0C60 +0C60 +1830 +1830 +3FF8 +3FF8 +3018 +600C +600C +C006 +C006 +0004 +0008 +0008 +000E +ENDCHAR +STARTCHAR 0105 +ENCODING 261 +SWIDTH 540 0 +DWIDTH 12 0 +BBX 10 16 1 -4 +BITMAP +3E00 +7F00 +C180 +C180 +0780 +7F80 +7980 +C180 +C180 +C380 +7F80 +7CC0 +0080 +0100 +0100 +01C0 +ENDCHAR +STARTCHAR 0106 +ENCODING 262 +SWIDTH 720 0 +DWIDTH 16 0 +BBX 14 20 1 0 +BITMAP +0180 +0300 +0200 +0000 +07C0 +1FF0 +3838 +6018 +600C +C000 +C000 +C000 +C000 +C000 +C000 +600C +6018 +3838 +1FF0 +0FC0 +ENDCHAR +STARTCHAR 0107 +ENCODING 263 +SWIDTH 495 0 +DWIDTH 11 0 +BBX 9 16 1 0 +BITMAP +0600 +0C00 +0800 +0000 +1E00 +7F00 +6380 +C180 +C000 +C000 +C000 +C000 +C180 +6380 +7F00 +1E00 +ENDCHAR +STARTCHAR 0108 +ENCODING 264 +SWIDTH 720 0 +DWIDTH 16 0 +BBX 14 20 1 0 +BITMAP +0300 +0780 +0CC0 +0000 +07C0 +1FF0 +3838 +6018 +600C +C000 +C000 +C000 +C000 +C000 +C000 +600C +6018 +3838 +1FF0 +0FC0 +ENDCHAR +STARTCHAR 0109 +ENCODING 265 +SWIDTH 495 0 +DWIDTH 11 0 +BBX 9 16 1 0 +BITMAP +0C00 +1E00 +3300 +0000 +1E00 +7F00 +6380 +C180 +C000 +C000 +C000 +C000 +C180 +6380 +7F00 +1E00 +ENDCHAR +STARTCHAR 010A +ENCODING 266 +SWIDTH 720 0 +DWIDTH 16 0 +BBX 14 19 1 0 +BITMAP +0180 +0180 +0000 +07C0 +1FF0 +3838 +6018 +600C +C000 +C000 +C000 +C000 +C000 +C000 +600C +6018 +3838 +1FF0 +0FC0 +ENDCHAR +STARTCHAR 010B +ENCODING 267 +SWIDTH 495 0 +DWIDTH 11 0 +BBX 9 15 1 0 +BITMAP +0C00 +0C00 +0000 +1E00 +7F00 +6380 +C180 +C000 +C000 +C000 +C000 +C180 +6380 +7F00 +1E00 +ENDCHAR +STARTCHAR 010C +ENCODING 268 +SWIDTH 720 0 +DWIDTH 16 0 +BBX 14 20 1 0 +BITMAP +0CC0 +0780 +0300 +0000 +07C0 +1FF0 +3838 +6018 +600C +C000 +C000 +C000 +C000 +C000 +C000 +600C +6018 +3838 +1FF0 +0FC0 +ENDCHAR +STARTCHAR 010D +ENCODING 269 +SWIDTH 495 0 +DWIDTH 11 0 +BBX 9 16 1 0 +BITMAP +3300 +1E00 +0C00 +0000 +1E00 +7F00 +6380 +C180 +C000 +C000 +C000 +C000 +C180 +6380 +7F00 +1E00 +ENDCHAR +STARTCHAR 010E +ENCODING 270 +SWIDTH 720 0 +DWIDTH 16 0 +BBX 13 20 2 0 +BITMAP +3300 +1E00 +0C00 +0000 +FF80 +FFE0 +C070 +C030 +C038 +C018 +C018 +C018 +C018 +C018 +C018 +C030 +C030 +C0E0 +FFE0 +FF80 +ENDCHAR +STARTCHAR 010F +ENCODING 271 +SWIDTH 630 0 +DWIDTH 14 0 +BBX 13 16 1 0 +BITMAP +00D8 +00D8 +00C8 +00C8 +1ED0 +7FC0 +61C0 +C1C0 +C0C0 +C0C0 +C0C0 +C0C0 +E0C0 +61C0 +3FC0 +1EC0 +ENDCHAR +STARTCHAR 0110 +ENCODING 272 +SWIDTH 720 0 +DWIDTH 16 0 +BBX 15 16 0 0 +BITMAP +3FE0 +3FF8 +301C +300C +300E +3006 +3006 +FF06 +FF06 +3006 +3006 +300C +300C +303C +3FF8 +3FE0 +ENDCHAR +STARTCHAR 0111 +ENCODING 273 +SWIDTH 540 0 +DWIDTH 12 0 +BBX 11 16 1 0 +BITMAP +00C0 +0FE0 +0FE0 +00C0 +1EC0 +7FC0 +61C0 +C1C0 +C0C0 +C0C0 +C0C0 +C0C0 +E0C0 +61C0 +3FC0 +1EC0 +ENDCHAR +STARTCHAR 0112 +ENCODING 274 +SWIDTH 675 0 +DWIDTH 15 0 +BBX 12 19 2 0 +BITMAP +1F80 +1F80 +0000 +FFF0 +FFF0 +C000 +C000 +C000 +C000 +C000 +FFE0 +FFE0 +C000 +C000 +C000 +C000 +C000 +FFF0 +FFF0 +ENDCHAR +STARTCHAR 0113 +ENCODING 275 +SWIDTH 540 0 +DWIDTH 12 0 +BBX 10 15 1 0 +BITMAP +3F00 +3F00 +0000 +1E00 +7F80 +6180 +C0C0 +FFC0 +FFC0 +C000 +C000 +E0C0 +7180 +3F80 +1E00 +ENDCHAR +STARTCHAR 0114 +ENCODING 276 +SWIDTH 675 0 +DWIDTH 15 0 +BBX 12 20 2 0 +BITMAP +1040 +18C0 +0F80 +0000 +FFF0 +FFF0 +C000 +C000 +C000 +C000 +C000 +FFE0 +FFE0 +C000 +C000 +C000 +C000 +C000 +FFF0 +FFF0 +ENDCHAR +STARTCHAR 0115 +ENCODING 277 +SWIDTH 540 0 +DWIDTH 12 0 +BBX 10 16 1 0 +BITMAP +2080 +3180 +1F00 +0000 +1E00 +7F80 +6180 +C0C0 +FFC0 +FFC0 +C000 +C000 +E0C0 +7180 +3F80 +1E00 +ENDCHAR +STARTCHAR 0116 +ENCODING 278 +SWIDTH 675 0 +DWIDTH 15 0 +BBX 12 19 2 0 +BITMAP +0600 +0600 +0000 +FFF0 +FFF0 +C000 +C000 +C000 +C000 +C000 +FFE0 +FFE0 +C000 +C000 +C000 +C000 +C000 +FFF0 +FFF0 +ENDCHAR +STARTCHAR 0117 +ENCODING 279 +SWIDTH 540 0 +DWIDTH 12 0 +BBX 10 15 1 0 +BITMAP +0C00 +0C00 +0000 +1E00 +7F80 +6180 +C0C0 +FFC0 +FFC0 +C000 +C000 +E0C0 +7180 +3F80 +1E00 +ENDCHAR +STARTCHAR 0118 +ENCODING 280 +SWIDTH 675 0 +DWIDTH 15 0 +BBX 12 20 2 -4 +BITMAP +FFF0 +FFF0 +C000 +C000 +C000 +C000 +C000 +FFE0 +FFE0 +C000 +C000 +C000 +C000 +C000 +FFF0 +FFF0 +0020 +0040 +0040 +0070 +ENDCHAR +STARTCHAR 0119 +ENCODING 281 +SWIDTH 540 0 +DWIDTH 12 0 +BBX 10 16 1 -4 +BITMAP +1E00 +7F80 +6180 +C0C0 +FFC0 +FFC0 +C000 +C000 +E0C0 +7180 +3F80 +1E00 +0200 +0400 +0400 +0700 +ENDCHAR +STARTCHAR 011A +ENCODING 282 +SWIDTH 675 0 +DWIDTH 15 0 +BBX 12 20 2 0 +BITMAP +1980 +0F00 +0600 +0000 +FFF0 +FFF0 +C000 +C000 +C000 +C000 +C000 +FFE0 +FFE0 +C000 +C000 +C000 +C000 +C000 +FFF0 +FFF0 +ENDCHAR +STARTCHAR 011B +ENCODING 283 +SWIDTH 540 0 +DWIDTH 12 0 +BBX 10 16 1 0 +BITMAP +3300 +1E00 +0C00 +0000 +1E00 +7F80 +6180 +C0C0 +FFC0 +FFC0 +C000 +C000 +E0C0 +7180 +3F80 +1E00 +ENDCHAR +STARTCHAR 011C +ENCODING 284 +SWIDTH 765 0 +DWIDTH 17 0 +BBX 15 20 1 0 +BITMAP +0180 +03C0 +0660 +0000 +07E0 +1FF8 +381C +700C +6006 +C000 +C000 +C000 +C0FE +C0FE +C006 +6006 +7006 +381E +1FFC +07E0 +ENDCHAR +STARTCHAR 011D +ENCODING 285 +SWIDTH 540 0 +DWIDTH 12 0 +BBX 10 20 1 -4 +BITMAP +0C00 +1E00 +3300 +0000 +1EC0 +7FC0 +61C0 +E0C0 +C0C0 +C0C0 +C0C0 +C0C0 +C1C0 +61C0 +7FC0 +1EC0 +00C0 +C180 +FF80 +3E00 +ENDCHAR +STARTCHAR 011E +ENCODING 286 +SWIDTH 765 0 +DWIDTH 17 0 +BBX 15 20 1 0 +BITMAP +0410 +0630 +03E0 +0000 +07E0 +1FF8 +381C +700C +6006 +C000 +C000 +C000 +C0FE +C0FE +C006 +6006 +7006 +381E +1FFC +07E0 +ENDCHAR +STARTCHAR 011F +ENCODING 287 +SWIDTH 540 0 +DWIDTH 12 0 +BBX 10 20 1 -4 +BITMAP +2080 +3180 +1F00 +0000 +1EC0 +7FC0 +61C0 +E0C0 +C0C0 +C0C0 +C0C0 +C0C0 +C1C0 +61C0 +7FC0 +1EC0 +00C0 +C180 +FF80 +3E00 +ENDCHAR +STARTCHAR 0120 +ENCODING 288 +SWIDTH 765 0 +DWIDTH 17 0 +BBX 15 19 1 0 +BITMAP +0180 +0180 +0000 +07E0 +1FF8 +381C +700C +6006 +C000 +C000 +C000 +C0FE +C0FE +C006 +6006 +7006 +381E +1FFC +07E0 +ENDCHAR +STARTCHAR 0121 +ENCODING 289 +SWIDTH 540 0 +DWIDTH 12 0 +BBX 10 19 1 -4 +BITMAP +0C00 +0C00 +0000 +1EC0 +7FC0 +61C0 +E0C0 +C0C0 +C0C0 +C0C0 +C0C0 +C1C0 +61C0 +7FC0 +1EC0 +00C0 +C180 +FF80 +3E00 +ENDCHAR +STARTCHAR 0122 +ENCODING 290 +SWIDTH 765 0 +DWIDTH 17 0 +BBX 15 23 1 -7 +BITMAP +07E0 +1FF8 +381C +700C +6006 +C000 +C000 +C000 +C0FE +C0FE +C006 +6006 +7006 +381E +1FFC +07E0 +0000 +0000 +00C0 +00C0 +0040 +00C0 +0080 +ENDCHAR +STARTCHAR 0123 +ENCODING 291 +SWIDTH 540 0 +DWIDTH 12 0 +BBX 10 22 1 -4 +BITMAP +0400 +0800 +0800 +0C00 +0C00 +0000 +1EC0 +7FC0 +61C0 +E1C0 +C0C0 +C0C0 +C0C0 +C0C0 +C1C0 +61C0 +7FC0 +1EC0 +00C0 +C180 +FF80 +3E00 +ENDCHAR +STARTCHAR 0124 +ENCODING 292 +SWIDTH 720 0 +DWIDTH 16 0 +BBX 12 20 2 0 +BITMAP +0600 +0F00 +1980 +0000 +C030 +C030 +C030 +C030 +C030 +C030 +C030 +FFF0 +FFF0 +C030 +C030 +C030 +C030 +C030 +C030 +C030 +ENDCHAR +STARTCHAR 0125 +ENCODING 293 +SWIDTH 495 0 +DWIDTH 11 0 +BBX 9 20 1 0 +BITMAP +0C00 +1E00 +3300 +0000 +C000 +C000 +C000 +C000 +DE00 +FF00 +E380 +C180 +C180 +C180 +C180 +C180 +C180 +C180 +C180 +C180 +ENDCHAR +STARTCHAR 0126 +ENCODING 294 +SWIDTH 720 0 +DWIDTH 16 0 +BBX 14 16 1 0 +BITMAP +6018 +6018 +FFFC +FFFC +6018 +6018 +7FF8 +7FF8 +6018 +6018 +6018 +6018 +6018 +6018 +6018 +6018 +ENDCHAR +STARTCHAR 0127 +ENCODING 295 +SWIDTH 495 0 +DWIDTH 11 0 +BBX 10 16 0 0 +BITMAP +6000 +FE00 +FE00 +6000 +6F00 +7F80 +70C0 +60C0 +60C0 +60C0 +60C0 +60C0 +60C0 +60C0 +60C0 +60C0 +ENDCHAR +STARTCHAR 0128 +ENCODING 296 +SWIDTH 270 0 +DWIDTH 6 0 +BBX 7 20 0 0 +BITMAP +76 +FE +DC +00 +30 +30 +30 +30 +30 +30 +30 +30 +30 +30 +30 +30 +30 +30 +30 +30 +ENDCHAR +STARTCHAR 0129 +ENCODING 297 +SWIDTH 270 0 +DWIDTH 6 0 +BBX 7 16 0 0 +BITMAP +76 +FE +DC +00 +30 +30 +30 +30 +30 +30 +30 +30 +30 +30 +30 +30 +ENDCHAR +STARTCHAR 012A +ENCODING 298 +SWIDTH 270 0 +DWIDTH 6 0 +BBX 6 19 0 0 +BITMAP +FC +FC +00 +30 +30 +30 +30 +30 +30 +30 +30 +30 +30 +30 +30 +30 +30 +30 +30 +ENDCHAR +STARTCHAR 012B +ENCODING 299 +SWIDTH 270 0 +DWIDTH 6 0 +BBX 6 15 0 0 +BITMAP +FC +FC +00 +30 +30 +30 +30 +30 +30 +30 +30 +30 +30 +30 +30 +ENDCHAR +STARTCHAR 012C +ENCODING 300 +SWIDTH 270 0 +DWIDTH 6 0 +BBX 7 20 0 0 +BITMAP +82 +C6 +7C +00 +30 +30 +30 +30 +30 +30 +30 +30 +30 +30 +30 +30 +30 +30 +30 +30 +ENDCHAR +STARTCHAR 012D +ENCODING 301 +SWIDTH 270 0 +DWIDTH 6 0 +BBX 7 16 0 0 +BITMAP +82 +C6 +7C +00 +30 +30 +30 +30 +30 +30 +30 +30 +30 +30 +30 +30 +ENDCHAR +STARTCHAR 012E +ENCODING 302 +SWIDTH 270 0 +DWIDTH 6 0 +BBX 3 20 1 -4 +BITMAP +60 +60 +60 +60 +60 +60 +60 +60 +60 +60 +60 +60 +60 +60 +60 +60 +40 +80 +80 +E0 +ENDCHAR +STARTCHAR 012F +ENCODING 303 +SWIDTH 225 0 +DWIDTH 5 0 +BBX 3 20 0 -4 +BITMAP +60 +60 +00 +00 +60 +60 +60 +60 +60 +60 +60 +60 +60 +60 +60 +60 +40 +80 +80 +E0 +ENDCHAR +STARTCHAR 0130 +ENCODING 304 +SWIDTH 270 0 +DWIDTH 6 0 +BBX 2 19 2 0 +BITMAP +C0 +C0 +00 +C0 +C0 +C0 +C0 +C0 +C0 +C0 +C0 +C0 +C0 +C0 +C0 +C0 +C0 +C0 +C0 +ENDCHAR +STARTCHAR 0131 +ENCODING 305 +SWIDTH 270 0 +DWIDTH 6 0 +BBX 2 12 2 0 +BITMAP +C0 +C0 +C0 +C0 +C0 +C0 +C0 +C0 +C0 +C0 +C0 +C0 +ENDCHAR +STARTCHAR 0132 +ENCODING 306 +SWIDTH 720 0 +DWIDTH 16 0 +BBX 12 16 2 0 +BITMAP +C030 +C030 +C030 +C030 +C030 +C030 +C030 +C030 +C030 +C030 +C030 +CC30 +CC30 +CE70 +C7E0 +C3C0 +ENDCHAR +STARTCHAR 0133 +ENCODING 307 +SWIDTH 450 0 +DWIDTH 10 0 +BBX 7 20 1 -4 +BITMAP +C6 +C6 +00 +00 +C6 +C6 +C6 +C6 +C6 +C6 +C6 +C6 +C6 +C6 +C6 +C6 +06 +06 +1E +1C +ENDCHAR +STARTCHAR 0134 +ENCODING 308 +SWIDTH 495 0 +DWIDTH 11 0 +BBX 10 20 1 0 +BITMAP +0300 +0780 +0CC0 +0000 +0300 +0300 +0300 +0300 +0300 +0300 +0300 +0300 +0300 +0300 +0300 +C300 +C300 +E700 +7E00 +3C00 +ENDCHAR +STARTCHAR 0135 +ENCODING 309 +SWIDTH 180 0 +DWIDTH 4 0 +BBX 6 20 -1 -4 +BITMAP +30 +78 +CC +00 +30 +30 +30 +30 +30 +30 +30 +30 +30 +30 +30 +30 +30 +30 +F0 +E0 +ENDCHAR +STARTCHAR 0136 +ENCODING 310 +SWIDTH 675 0 +DWIDTH 15 0 +BBX 13 23 2 -7 +BITMAP +C070 +C0E0 +C1C0 +C380 +C700 +CE00 +DC00 +FC00 +FE00 +E700 +C380 +C1C0 +C0C0 +C0E0 +C070 +C038 +0000 +0000 +0600 +0600 +0200 +0600 +0400 +ENDCHAR +STARTCHAR 0137 +ENCODING 311 +SWIDTH 450 0 +DWIDTH 10 0 +BBX 9 23 1 -7 +BITMAP +C000 +C000 +C000 +C000 +C380 +C700 +CE00 +DC00 +F800 +FC00 +EC00 +CE00 +C600 +C700 +C300 +C380 +0000 +0000 +0C00 +0C00 +0400 +0C00 +0800 +ENDCHAR +STARTCHAR 0138 +ENCODING 312 +SWIDTH 495 0 +DWIDTH 11 0 +BBX 9 12 1 0 +BITMAP +C180 +C300 +C600 +CC00 +D800 +F800 +CC00 +C600 +C600 +C300 +C180 +C180 +ENDCHAR +STARTCHAR 0139 +ENCODING 313 +SWIDTH 540 0 +DWIDTH 12 0 +BBX 9 20 2 0 +BITMAP +1800 +3000 +2000 +0000 +C000 +C000 +C000 +C000 +C000 +C000 +C000 +C000 +C000 +C000 +C000 +C000 +C000 +C000 +FF80 +FF80 +ENDCHAR +STARTCHAR 013A +ENCODING 314 +SWIDTH 180 0 +DWIDTH 4 0 +BBX 3 20 1 0 +BITMAP +60 +C0 +80 +00 +C0 +C0 +C0 +C0 +C0 +C0 +C0 +C0 +C0 +C0 +C0 +C0 +C0 +C0 +C0 +C0 +ENDCHAR +STARTCHAR 013B +ENCODING 315 +SWIDTH 540 0 +DWIDTH 12 0 +BBX 9 23 2 -7 +BITMAP +C000 +C000 +C000 +C000 +C000 +C000 +C000 +C000 +C000 +C000 +C000 +C000 +C000 +C000 +FF80 +FF80 +0000 +0000 +0C00 +0C00 +0400 +0C00 +0800 +ENDCHAR +STARTCHAR 013C +ENCODING 316 +SWIDTH 180 0 +DWIDTH 4 0 +BBX 2 23 1 -7 +BITMAP +C0 +C0 +C0 +C0 +C0 +C0 +C0 +C0 +C0 +C0 +C0 +C0 +C0 +C0 +C0 +C0 +00 +00 +C0 +C0 +40 +C0 +80 +ENDCHAR +STARTCHAR 013D +ENCODING 317 +SWIDTH 540 0 +DWIDTH 12 0 +BBX 9 16 2 0 +BITMAP +C300 +C300 +C100 +C100 +C200 +C000 +C000 +C000 +C000 +C000 +C000 +C000 +C000 +C000 +FF80 +FF80 +ENDCHAR +STARTCHAR 013E +ENCODING 318 +SWIDTH 315 0 +DWIDTH 7 0 +BBX 5 16 2 0 +BITMAP +D8 +D8 +C8 +C8 +D0 +C0 +C0 +C0 +C0 +C0 +C0 +C0 +C0 +C0 +C0 +C0 +ENDCHAR +STARTCHAR 013F +ENCODING 319 +SWIDTH 540 0 +DWIDTH 12 0 +BBX 9 16 2 0 +BITMAP +C000 +C000 +C000 +C000 +C000 +C000 +C000 +C600 +C600 +C000 +C000 +C000 +C000 +C000 +FF80 +FF80 +ENDCHAR +STARTCHAR 0140 +ENCODING 320 +SWIDTH 315 0 +DWIDTH 7 0 +BBX 6 16 1 0 +BITMAP +C0 +C0 +C0 +C0 +C0 +C0 +C0 +CC +CC +C0 +C0 +C0 +C0 +C0 +C0 +C0 +ENDCHAR +STARTCHAR 0141 +ENCODING 321 +SWIDTH 540 0 +DWIDTH 12 0 +BBX 11 16 0 0 +BITMAP +3000 +3000 +3000 +3100 +3300 +3600 +3C00 +3800 +7000 +F000 +B000 +3000 +3000 +3000 +3FE0 +3FE0 +ENDCHAR +STARTCHAR 0142 +ENCODING 322 +SWIDTH 180 0 +DWIDTH 4 0 +BBX 4 16 0 0 +BITMAP +60 +60 +60 +60 +60 +70 +70 +60 +E0 +E0 +60 +60 +60 +60 +60 +60 +ENDCHAR +STARTCHAR 0143 +ENCODING 323 +SWIDTH 720 0 +DWIDTH 16 0 +BBX 12 20 2 0 +BITMAP +0300 +0600 +0400 +0000 +C030 +E030 +F030 +F030 +D830 +D830 +CC30 +C630 +C630 +C330 +C1B0 +C1B0 +C0F0 +C0F0 +C070 +C030 +ENDCHAR +STARTCHAR 0144 +ENCODING 324 +SWIDTH 495 0 +DWIDTH 11 0 +BBX 9 16 1 0 +BITMAP +0600 +0C00 +0800 +0000 +DE00 +FF00 +E380 +C180 +C180 +C180 +C180 +C180 +C180 +C180 +C180 +C180 +ENDCHAR +STARTCHAR 0145 +ENCODING 325 +SWIDTH 720 0 +DWIDTH 16 0 +BBX 12 23 2 -7 +BITMAP +C030 +E030 +F030 +F030 +D830 +D830 +CC30 +C630 +C630 +C330 +C1B0 +C1B0 +C0F0 +C0F0 +C070 +C030 +0000 +0000 +0600 +0600 +0200 +0600 +0400 +ENDCHAR +STARTCHAR 0146 +ENCODING 326 +SWIDTH 495 0 +DWIDTH 11 0 +BBX 9 19 1 -7 +BITMAP +DE00 +FF00 +E380 +C180 +C180 +C180 +C180 +C180 +C180 +C180 +C180 +C180 +0000 +0000 +0C00 +0C00 +0400 +0C00 +0800 +ENDCHAR +STARTCHAR 0147 +ENCODING 327 +SWIDTH 720 0 +DWIDTH 16 0 +BBX 12 20 2 0 +BITMAP +1980 +0F00 +0600 +0000 +C030 +E030 +F030 +F030 +D830 +D830 +CC30 +C630 +C630 +C330 +C1B0 +C1B0 +C0F0 +C0F0 +C070 +C030 +ENDCHAR +STARTCHAR 0148 +ENCODING 328 +SWIDTH 495 0 +DWIDTH 11 0 +BBX 9 16 1 0 +BITMAP +3300 +1E00 +0C00 +0000 +DE00 +FF00 +E380 +C180 +C180 +C180 +C180 +C180 +C180 +C180 +C180 +C180 +ENDCHAR +STARTCHAR 0149 +ENCODING 329 +SWIDTH 585 0 +DWIDTH 13 0 +BBX 12 16 0 0 +BITMAP +C000 +C000 +4000 +4000 +9BC0 +1FE0 +1C70 +1830 +1830 +1830 +1830 +1830 +1830 +1830 +1830 +1830 +ENDCHAR +STARTCHAR 014A +ENCODING 330 +SWIDTH 720 0 +DWIDTH 16 0 +BBX 13 16 2 0 +BITMAP +CFC0 +DFE0 +F070 +E030 +C038 +C018 +C018 +C018 +C018 +C018 +C018 +C018 +C030 +C070 +C7E0 +C3C0 +ENDCHAR +STARTCHAR 014B +ENCODING 331 +SWIDTH 540 0 +DWIDTH 12 0 +BBX 10 16 1 -4 +BITMAP +DF00 +FF80 +E1C0 +C0C0 +C0C0 +C0C0 +C0C0 +C0C0 +C0C0 +C0C0 +C0C0 +C0C0 +00C0 +00C0 +03C0 +0380 +ENDCHAR +STARTCHAR 014C +ENCODING 332 +SWIDTH 765 0 +DWIDTH 17 0 +BBX 15 19 1 0 +BITMAP +07E0 +07E0 +0000 +07C0 +1FF0 +3838 +701C +600C +C006 +C006 +C006 +C006 +C006 +C006 +600C +701C +3838 +1FF0 +07C0 +ENDCHAR +STARTCHAR 014D +ENCODING 333 +SWIDTH 585 0 +DWIDTH 13 0 +BBX 11 15 1 0 +BITMAP +3F00 +3F00 +0000 +1F00 +3F80 +71C0 +E0E0 +C060 +C060 +C060 +C060 +E0E0 +71C0 +3F80 +1F00 +ENDCHAR +STARTCHAR 014E +ENCODING 334 +SWIDTH 765 0 +DWIDTH 17 0 +BBX 15 20 1 0 +BITMAP +0820 +0C60 +07C0 +0000 +07C0 +1FF0 +3838 +701C +600C +C006 +C006 +C006 +C006 +C006 +C006 +600C +701C +3838 +1FF0 +07C0 +ENDCHAR +STARTCHAR 014F +ENCODING 335 +SWIDTH 585 0 +DWIDTH 13 0 +BBX 11 16 1 0 +BITMAP +2080 +3180 +1F00 +0000 +1F00 +3F80 +71C0 +E0E0 +C060 +C060 +C060 +C060 +E0E0 +71C0 +3F80 +1F00 +ENDCHAR +STARTCHAR 0150 +ENCODING 336 +SWIDTH 765 0 +DWIDTH 17 0 +BBX 15 20 1 0 +BITMAP +0660 +0CC0 +0CC0 +0000 +07C0 +1FF0 +3838 +701C +600C +C006 +C006 +C006 +C006 +C006 +C006 +600C +701C +3838 +1FF0 +07C0 +ENDCHAR +STARTCHAR 0151 +ENCODING 337 +SWIDTH 585 0 +DWIDTH 13 0 +BBX 11 16 1 0 +BITMAP +1980 +3300 +3300 +0000 +1F00 +3F80 +71C0 +E0E0 +C060 +C060 +C060 +C060 +E0E0 +71C0 +3F80 +1F00 +ENDCHAR +STARTCHAR 0152 +ENCODING 338 +SWIDTH 990 0 +DWIDTH 22 0 +BBX 20 16 1 0 +BITMAP +0F9FF0 +3FDFF0 +787800 +603800 +603800 +C01800 +C01800 +C01FE0 +C01FE0 +C01800 +C01800 +603800 +603800 +707800 +3FDFF0 +0F9FF0 +ENDCHAR +STARTCHAR 0153 +ENCODING 339 +SWIDTH 945 0 +DWIDTH 21 0 +BBX 19 12 1 0 +BITMAP +1F0F00 +3F9F80 +71F0C0 +E0E060 +C06060 +C07FE0 +C07FE0 +C06000 +E0E060 +71F0C0 +3F9FC0 +1F0F80 +ENDCHAR +STARTCHAR 0154 +ENCODING 340 +SWIDTH 720 0 +DWIDTH 16 0 +BBX 12 20 2 0 +BITMAP +0600 +0C00 +0800 +0000 +FFC0 +FFE0 +C070 +C030 +C030 +C030 +C070 +FFE0 +FFC0 +C300 +C180 +C1C0 +C0E0 +C060 +C070 +C030 +ENDCHAR +STARTCHAR 0155 +ENCODING 341 +SWIDTH 315 0 +DWIDTH 7 0 +BBX 6 16 1 0 +BITMAP +0C +18 +10 +00 +DC +FC +E0 +C0 +C0 +C0 +C0 +C0 +C0 +C0 +C0 +C0 +ENDCHAR +STARTCHAR 0156 +ENCODING 342 +SWIDTH 720 0 +DWIDTH 16 0 +BBX 12 23 2 -7 +BITMAP +FFC0 +FFE0 +C070 +C030 +C030 +C030 +C070 +FFE0 +FFC0 +C300 +C180 +C1C0 +C0E0 +C060 +C070 +C030 +0000 +0000 +0600 +0600 +0200 +0600 +0400 +ENDCHAR +STARTCHAR 0157 +ENCODING 343 +SWIDTH 315 0 +DWIDTH 7 0 +BBX 6 19 1 -7 +BITMAP +DC +FC +E0 +C0 +C0 +C0 +C0 +C0 +C0 +C0 +C0 +C0 +00 +00 +C0 +C0 +40 +C0 +80 +ENDCHAR +STARTCHAR 0158 +ENCODING 344 +SWIDTH 720 0 +DWIDTH 16 0 +BBX 12 20 2 0 +BITMAP +3300 +1E00 +0C00 +0000 +FFC0 +FFE0 +C070 +C030 +C030 +C030 +C070 +FFE0 +FFC0 +C300 +C180 +C1C0 +C0E0 +C060 +C070 +C030 +ENDCHAR +STARTCHAR 0159 +ENCODING 345 +SWIDTH 315 0 +DWIDTH 7 0 +BBX 6 16 1 0 +BITMAP +CC +78 +30 +00 +DC +FC +E0 +C0 +C0 +C0 +C0 +C0 +C0 +C0 +C0 +C0 +ENDCHAR +STARTCHAR 015A +ENCODING 346 +SWIDTH 675 0 +DWIDTH 15 0 +BBX 13 20 1 0 +BITMAP +0180 +0300 +0200 +0000 +0FC0 +3FE0 +7070 +6018 +6018 +7000 +3C00 +1FC0 +03F0 +0038 +C018 +C018 +6018 +7070 +3FF0 +0FC0 +ENDCHAR +STARTCHAR 015B +ENCODING 347 +SWIDTH 495 0 +DWIDTH 11 0 +BBX 9 16 1 0 +BITMAP +0600 +0C00 +0800 +0000 +3E00 +7F00 +C180 +C000 +F000 +7E00 +1F80 +0380 +0180 +C380 +7F00 +3E00 +ENDCHAR +STARTCHAR 015C +ENCODING 348 +SWIDTH 675 0 +DWIDTH 15 0 +BBX 13 20 1 0 +BITMAP +0300 +0780 +0CC0 +0000 +0FC0 +3FE0 +7070 +6018 +6018 +7000 +3C00 +1FC0 +03F0 +0038 +C018 +C018 +6018 +7070 +3FF0 +0FC0 +ENDCHAR +STARTCHAR 015D +ENCODING 349 +SWIDTH 495 0 +DWIDTH 11 0 +BBX 9 16 1 0 +BITMAP +0C00 +1E00 +3300 +0000 +3E00 +7F00 +C180 +C000 +F000 +7E00 +1F80 +0380 +0180 +C380 +7F00 +3E00 +ENDCHAR +STARTCHAR 015E +ENCODING 350 +SWIDTH 675 0 +DWIDTH 15 0 +BBX 13 20 1 -4 +BITMAP +0FC0 +3FE0 +7070 +6018 +6018 +7000 +3C00 +1FC0 +03F0 +0038 +C018 +C018 +6018 +7070 +3FF0 +0FC0 +0200 +0300 +0180 +0F00 +ENDCHAR +STARTCHAR 015F +ENCODING 351 +SWIDTH 495 0 +DWIDTH 11 0 +BBX 9 16 1 -4 +BITMAP +3E00 +7F00 +C180 +C000 +F000 +7E00 +1F80 +0380 +0180 +C380 +7F00 +3E00 +0800 +0C00 +0600 +3C00 +ENDCHAR +STARTCHAR 0160 +ENCODING 352 +SWIDTH 675 0 +DWIDTH 15 0 +BBX 13 20 1 0 +BITMAP +0CC0 +0780 +0300 +0000 +0FC0 +3FE0 +7070 +6018 +6018 +7000 +3C00 +1FC0 +03F0 +0038 +C018 +C018 +6018 +7070 +3FF0 +0FC0 +ENDCHAR +STARTCHAR 0161 +ENCODING 353 +SWIDTH 495 0 +DWIDTH 11 0 +BBX 9 16 1 0 +BITMAP +3300 +1E00 +0C00 +0000 +3E00 +7F00 +C180 +C000 +F000 +7E00 +1F80 +0380 +0180 +C380 +7F00 +3E00 +ENDCHAR +STARTCHAR 0162 +ENCODING 354 +SWIDTH 630 0 +DWIDTH 14 0 +BBX 12 20 1 -4 +BITMAP +FFF0 +FFF0 +0600 +0600 +0600 +0600 +0600 +0600 +0600 +0600 +0600 +0600 +0600 +0600 +0600 +0600 +0200 +0300 +0180 +0F00 +ENDCHAR +STARTCHAR 0163 +ENCODING 355 +SWIDTH 270 0 +DWIDTH 6 0 +BBX 6 20 0 -4 +BITMAP +20 +60 +60 +60 +F8 +F8 +60 +60 +60 +60 +60 +60 +60 +60 +78 +38 +10 +18 +0C +78 +ENDCHAR +STARTCHAR 0164 +ENCODING 356 +SWIDTH 630 0 +DWIDTH 14 0 +BBX 12 20 1 0 +BITMAP +1980 +0F00 +0600 +0000 +FFF0 +FFF0 +0600 +0600 +0600 +0600 +0600 +0600 +0600 +0600 +0600 +0600 +0600 +0600 +0600 +0600 +ENDCHAR +STARTCHAR 0165 +ENCODING 357 +SWIDTH 360 0 +DWIDTH 8 0 +BBX 7 16 1 0 +BITMAP +26 +66 +62 +62 +FC +F8 +60 +60 +60 +60 +60 +60 +60 +60 +78 +38 +ENDCHAR +STARTCHAR 0166 +ENCODING 358 +SWIDTH 585 0 +DWIDTH 13 0 +BBX 12 16 1 0 +BITMAP +FFF0 +FFF0 +0600 +0600 +0600 +0600 +0600 +0600 +3FC0 +3FC0 +0600 +0600 +0600 +0600 +0600 +0600 +ENDCHAR +STARTCHAR 0167 +ENCODING 359 +SWIDTH 270 0 +DWIDTH 6 0 +BBX 5 15 0 0 +BITMAP +60 +60 +60 +F8 +F8 +60 +60 +60 +F8 +F8 +60 +60 +60 +78 +38 +ENDCHAR +STARTCHAR 0168 +ENCODING 360 +SWIDTH 720 0 +DWIDTH 16 0 +BBX 12 20 2 0 +BITMAP +0EC0 +1FC0 +1B80 +0000 +C030 +C030 +C030 +C030 +C030 +C030 +C030 +C030 +C030 +C030 +C030 +C030 +E070 +70E0 +3FC0 +1F80 +ENDCHAR +STARTCHAR 0169 +ENCODING 361 +SWIDTH 495 0 +DWIDTH 11 0 +BBX 9 16 1 0 +BITMAP +3B00 +7F00 +6E00 +0000 +C180 +C180 +C180 +C180 +C180 +C180 +C180 +C180 +C180 +E380 +7F80 +3D80 +ENDCHAR +STARTCHAR 016A +ENCODING 362 +SWIDTH 720 0 +DWIDTH 16 0 +BBX 12 19 2 0 +BITMAP +1F80 +1F80 +0000 +C030 +C030 +C030 +C030 +C030 +C030 +C030 +C030 +C030 +C030 +C030 +C030 +E070 +70E0 +3FC0 +1F80 +ENDCHAR +STARTCHAR 016B +ENCODING 363 +SWIDTH 495 0 +DWIDTH 11 0 +BBX 9 15 1 0 +BITMAP +3F00 +3F00 +0000 +C180 +C180 +C180 +C180 +C180 +C180 +C180 +C180 +C180 +E380 +7F80 +3D80 +ENDCHAR +STARTCHAR 016C +ENCODING 364 +SWIDTH 720 0 +DWIDTH 16 0 +BBX 12 20 2 0 +BITMAP +1040 +18C0 +0F80 +0000 +C030 +C030 +C030 +C030 +C030 +C030 +C030 +C030 +C030 +C030 +C030 +C030 +E070 +70E0 +3FC0 +1F80 +ENDCHAR +STARTCHAR 016D +ENCODING 365 +SWIDTH 495 0 +DWIDTH 11 0 +BBX 9 16 1 0 +BITMAP +2080 +3180 +1F00 +0000 +C180 +C180 +C180 +C180 +C180 +C180 +C180 +C180 +C180 +E380 +7F80 +3D80 +ENDCHAR +STARTCHAR 016E +ENCODING 366 +SWIDTH 720 0 +DWIDTH 16 0 +BBX 12 20 2 0 +BITMAP +0700 +0880 +0880 +0880 +C730 +C030 +C030 +C030 +C030 +C030 +C030 +C030 +C030 +C030 +C030 +C030 +E070 +70E0 +3FC0 +1F80 +ENDCHAR +STARTCHAR 016F +ENCODING 367 +SWIDTH 495 0 +DWIDTH 11 0 +BBX 9 18 1 0 +BITMAP +1C00 +2200 +2200 +2200 +1C00 +0000 +C180 +C180 +C180 +C180 +C180 +C180 +C180 +C180 +C180 +E380 +7F80 +3D80 +ENDCHAR +STARTCHAR 0170 +ENCODING 368 +SWIDTH 720 0 +DWIDTH 16 0 +BBX 12 20 2 0 +BITMAP +0CC0 +1980 +1980 +0000 +C030 +C030 +C030 +C030 +C030 +C030 +C030 +C030 +C030 +C030 +C030 +C030 +E070 +70E0 +3FC0 +1F80 +ENDCHAR +STARTCHAR 0171 +ENCODING 369 +SWIDTH 495 0 +DWIDTH 11 0 +BBX 9 16 1 0 +BITMAP +3300 +6600 +6600 +0000 +C180 +C180 +C180 +C180 +C180 +C180 +C180 +C180 +C180 +E380 +7F80 +3D80 +ENDCHAR +STARTCHAR 0172 +ENCODING 370 +SWIDTH 720 0 +DWIDTH 16 0 +BBX 12 20 2 -4 +BITMAP +C030 +C030 +C030 +C030 +C030 +C030 +C030 +C030 +C030 +C030 +C030 +C030 +E070 +70E0 +3FC0 +1F80 +0100 +0200 +0200 +0380 +ENDCHAR +STARTCHAR 0173 +ENCODING 371 +SWIDTH 495 0 +DWIDTH 11 0 +BBX 9 16 1 -4 +BITMAP +C180 +C180 +C180 +C180 +C180 +C180 +C180 +C180 +C180 +E380 +7F80 +3D80 +0100 +0200 +0200 +0380 +ENDCHAR +STARTCHAR 0174 +ENCODING 372 +SWIDTH 945 0 +DWIDTH 21 0 +BBX 21 20 0 0 +BITMAP +003000 +007800 +00CC00 +000000 +C07018 +C07018 +60D830 +60D830 +60D830 +60D830 +318C60 +318C60 +318C60 +318C60 +1B06C0 +1B06C0 +1B06C0 +1B06C0 +0E0380 +0E0380 +ENDCHAR +STARTCHAR 0175 +ENCODING 373 +SWIDTH 675 0 +DWIDTH 15 0 +BBX 15 16 0 0 +BITMAP +0180 +03C0 +0660 +0000 +C106 +C386 +C386 +628C +66CC +26C8 +36D8 +36D8 +1450 +1C70 +1C70 +0C60 +ENDCHAR +STARTCHAR 0176 +ENCODING 374 +SWIDTH 630 0 +DWIDTH 14 0 +BBX 14 20 0 0 +BITMAP +0300 +0780 +0CC0 +0000 +E01C +6018 +3030 +3870 +1860 +0CC0 +0FC0 +0780 +0300 +0300 +0300 +0300 +0300 +0300 +0300 +0300 +ENDCHAR +STARTCHAR 0177 +ENCODING 375 +SWIDTH 495 0 +DWIDTH 11 0 +BBX 11 20 0 -4 +BITMAP +0600 +0F00 +1980 +0000 +C060 +C060 +60C0 +60C0 +30C0 +3180 +1980 +1980 +0F00 +0F00 +0700 +0600 +0E00 +0C00 +7C00 +7800 +ENDCHAR +STARTCHAR 0178 +ENCODING 376 +SWIDTH 630 0 +DWIDTH 14 0 +BBX 14 19 0 0 +BITMAP +0CC0 +0CC0 +0000 +E01C +6018 +3030 +3870 +1860 +0CC0 +0FC0 +0780 +0300 +0300 +0300 +0300 +0300 +0300 +0300 +0300 +ENDCHAR +STARTCHAR 0179 +ENCODING 377 +SWIDTH 585 0 +DWIDTH 13 0 +BBX 12 20 0 0 +BITMAP +0180 +0300 +0200 +0000 +7FF0 +7FF0 +0060 +00C0 +00C0 +0180 +0300 +0600 +0600 +0C00 +1800 +3000 +3000 +6000 +FFF0 +FFF0 +ENDCHAR +STARTCHAR 017A +ENCODING 378 +SWIDTH 495 0 +DWIDTH 11 0 +BBX 10 16 0 0 +BITMAP +0300 +0600 +0400 +0000 +7FC0 +7FC0 +01C0 +0380 +0700 +0E00 +1C00 +3800 +7000 +E000 +FFC0 +FFC0 +ENDCHAR +STARTCHAR 017B +ENCODING 379 +SWIDTH 585 0 +DWIDTH 13 0 +BBX 12 19 0 0 +BITMAP +0300 +0300 +0000 +7FF0 +7FF0 +0060 +00C0 +00C0 +0180 +0300 +0600 +0600 +0C00 +1800 +3000 +3000 +6000 +FFF0 +FFF0 +ENDCHAR +STARTCHAR 017C +ENCODING 380 +SWIDTH 495 0 +DWIDTH 11 0 +BBX 10 15 0 0 +BITMAP +0600 +0600 +0000 +7FC0 +7FC0 +01C0 +0380 +0700 +0E00 +1C00 +3800 +7000 +E000 +FFC0 +FFC0 +ENDCHAR +STARTCHAR 017D +ENCODING 381 +SWIDTH 585 0 +DWIDTH 13 0 +BBX 12 20 0 0 +BITMAP +0CC0 +0780 +0300 +0000 +7FF0 +7FF0 +0060 +00C0 +00C0 +0180 +0300 +0600 +0600 +0C00 +1800 +3000 +3000 +6000 +FFF0 +FFF0 +ENDCHAR +STARTCHAR 017E +ENCODING 382 +SWIDTH 495 0 +DWIDTH 11 0 +BBX 10 16 0 0 +BITMAP +1980 +0F00 +0600 +0000 +7FC0 +7FC0 +01C0 +0380 +0700 +0E00 +1C00 +3800 +7000 +E000 +FFC0 +FFC0 +ENDCHAR +ENDFONT diff --git a/examples/fonts/Arial-16.bdf.license b/examples/fonts/Arial-16.bdf.license new file mode 100644 index 0000000..db3e0e3 --- /dev/null +++ b/examples/fonts/Arial-16.bdf.license @@ -0,0 +1,3 @@ +# SPDX-FileCopyrightText: 2017 The Monotype Corporation. All Rights Reserved. Hebrew OpenType Layout logic copyright © 2003 & 2007, Ralph Hancock & John Hudson. + +# SPDX-License-Identifier: MIT