From 96f8d20f2f3b130ae0cb76536df6b7c0c27fefc1 Mon Sep 17 00:00:00 2001 From: AnHardt Date: Fri, 13 Mar 2015 14:26:58 +0100 Subject: [PATCH] Change selection logic another time Automatic selection was to unflexible. Updated documentation Updated language files to new logic and documentation. Updated bdf2u8g.exe --- Documentation/LCDLanguageFont.md | 64 ++++++++++++++++------------ Marlin/Configuration.h | 7 ++-- Marlin/dogm_lcd_implementation.h | 70 ++++++++++++++++--------------- Marlin/language.h | 6 +++ Marlin/language_an.h | 5 ++- Marlin/language_ca.h | 5 ++- Marlin/language_de.h | 5 ++- Marlin/language_en.h | 10 ++++- Marlin/language_es.h | 5 ++- Marlin/language_eu.h | 5 ++- Marlin/language_fi.h | 5 ++- Marlin/language_fr.h | 6 ++- Marlin/language_it.h | 5 ++- Marlin/language_kana.h | 5 ++- Marlin/language_kana_utf8.h | 5 ++- Marlin/language_kanji.h | 2 +- Marlin/language_nl.h | 5 ++- Marlin/language_pl.h | 5 ++- Marlin/language_pt-br.h | 5 ++- Marlin/language_pt.h | 5 ++- Marlin/language_ru.h | 7 +++- Marlin/language_test.h | 26 ++++++++---- Marlin/scripts/Fonts/bdf2u8g.exe | Bin 19968 -> 56515 bytes Marlin/utf_mapper.h | 48 ++++++++++----------- 24 files changed, 194 insertions(+), 117 deletions(-) diff --git a/Documentation/LCDLanguageFont.md b/Documentation/LCDLanguageFont.md index a06b39160..13e70b90a 100644 --- a/Documentation/LCDLanguageFont.md +++ b/Documentation/LCDLanguageFont.md @@ -1,15 +1,15 @@ # LCD Language Font System -We deal with a variety of differend displays. -And we try to display different languages on them. +We deal with a variety of different displays. +And we try to display a lot of different languages on them. This system is ought to solve some of the related problems. ## The Displays -We have two different technologys for the displays: +We have two different technologies for the displays: * Character based displays Have a fixed set of symbols (charset - font) in their ROM. - All of them have similar but not identical symbols at the positions 0 to 127 similar to US-ASCII. + All of them have a similar but not identical symbol set at the positions 0 to 127 similar to US-ASCII. On the other hand symbols at places higher than 127 have mayor differences. Until now we know of (and support): 1.) HD44780 and similar with Kana charset A00 https://www.sparkfun.com/datasheets/LCD/HD44780.pdf Page 17 @@ -22,10 +22,10 @@ We have two different technologys for the displays: * Full graphic displays Where we have the full freedom to display whatever we want, when we can make a program for it. - Currently we deal with 128x64 Pixel Displays and devide this area in about 5 Lines with about 22 columns. + Currently we deal with 128x64 Pixel Displays and divide this area in about 5 Lines with about 22 columns. Therefore we need fonts with a bounding box of about 6x10. Until now we used a - 1.) Marlin-font similar to ISO10646-1 but with special Symbols at the end what made '' and '' unaccessible in the size 6x10. + 1.) Marlin-font similar to ISO10646-1 but with special Symbols at the end, what made 'ü' and 'ä' inaccessible, in the size 6x10. 2.) Because these letters are to big for some locations on the info-screen we use a full ISO10646-1 font in the size of 6x9. 3.) When we define USE_BIG_EDIT_FONT we use an additional ISO10646-1 font with 9x18, eating up another 3120 bytes of progmem - but readable without glasses. @@ -48,17 +48,18 @@ We have two different technologys for the displays: and recently on [Thingiverse](http://www.thingiverse.com/) a new port to * jp [Japanese](http://www.thingiverse.com/thing:664397) appeared. - + +## The Problem All of this languages, except the English, normally use extended symbol sets, not contained in US-ASCII. - Even the English translation uses some Symbols not in US-ASCII. ( '\002' for Thermometer, STR_h3 for '') - And worse, in the code itself symbols are used, not taking in account, on what display they are written. [(This is thrue only for Displays with Japanese charset](https://github.com/MarlinFirmware/Marlin/blob/Development/Marlin/ultralcd_implementation_hitachi_HD44780.h#L218) on Western displays you'll see a '~' and on Cyrillic an 'arrow coming from top - pointing to left', what is quite the opposite the programmer wanted.) - The Germans want to use "a" the Finnish at least "". Other European languages want to see their accents an their letters. + Even the English translation uses some Symbols not in US-ASCII. ( '\002' for Thermometer, STR_h3 for '³') + And worse, in the code itself symbols are used, not taking in account, on what display they are written. [(This is thrue only for Displays with Japanese charset](https://github.com/MarlinFirmware/Marlin/blob/Development/Marlin/ultralcd_implementation_hitachi_HD44780.h#L218) on Western displays you'll see a '~' and on Cyrillic an 'arrow coming from top - pointing to left', what is quite the opposite of the programmer wanted.) + The Germans want to use "ÄäÖöÜüß" the Finnish at least "äö". Other European languages want to see their accents an their letters. For other scripts like Cyrillic, Japanese, Greek, Hebrew, ... you have to find totally different symbol sets. Until now the problems where ignored widely. - The German translation used utf8 '' and '' and did not care about showing garbage on all displays. + The German translation used utf8 'ä' and 'ö' and did not care about showing garbage on ALL displays. The Russian translators new that their system only works on the Cyrillic character displays and relied on special LCD routines (LiquidCrystalRus.cpp) to handle UTF8 but missed to implement a proper strlen(). - The Japanese translator dealed with to scritps. He introduced a very special font for the full graphic displays and made use of the Japanese version of the character displays. Therefore he ended up with two pretty unreadable language.h files full of '\xxx' definitions. + The Japanese translator dealed with to scripts. He introduced a very special font for the full graphic displays and made use of the Japanese version of the character displays. Therefore he ended up with two pretty unreadable language.h files full of '\xxx' definitions. Other languages ether tried to avoid wording with their special symbols or ignored the problem at all and used the basic symbols without the accents, dots, ... whatever. ## The (partial) Solution @@ -74,15 +75,15 @@ We have two different technologys for the displays: ### Actions: a.) Declare the display hardware we use. (Configuration.h) b.) Declare the language ore script we use. (Configuration.h) - c.) Declare the kind of input we use. Ether direct pointers to the font (\xxx) or UTF8. (language_xx.h) + c.) Declare the kind of input we use. Ether direct pointers to the font (\xxx) or UTF8 and the font to use on graphic displays. (language_xx.h) d.) Declare the needed translations. (language_xx.h) e.) Make strlen() work with UTF8. (ultralcd.cpp) f.) Seperate the Marlin Symbols to their own font. (dogm_font_data_Marlin_symbols.h) g.) Make the fontswitch function remember the last used font. (dogm_lcd_implementation.h) - h.) Make output functions what count the number of written chars and switch the font to Marlin symbols and back when needed. (dogm_lcd_implementation.h) (ultralcd_implementation_hitachi_HD44780.h) - i.) Make three fonts to simulate the HD44780 charsets on dogm-displays. This makes translations easy because we have less charsets we have to deal with. (What is working on the HD44780s will also work on the dogms.) - j.) Make ISO fonts for Cyrillic and Katakana because they do not need a mapping table and are faster to deal with and have a better charset (less compromises) - k.) Make mapping functions and tables to convert from UTF8 to the fonts and integrate to the new output functions. (utf_mapper.h) + h.) Make output functions that count the number of written chars and switch the font to Marlin symbols and back when needed. (dogm_lcd_implementation.h) (ultralcd_implementation_hitachi_HD44780.h) + i.) Make three fonts to simulate the HD44780 charsets on dogm-displays. With this fonts the translator can check how his translation will look on the character based displays. + j.) Make ISO fonts for Cyrillic and Katakana because they do not need a mapping table and are faster to deal with and have a better charset (less compromises) than the HD44780 fonts. + k.) Make mapping functions and tables to convert from UTF8 to the fonts and integrate in the new output functions. (utf_mapper.h) l.) Delete the not needed any more 'LiquidCrystalRus.xxx' files and their calls in 'ultralcd_implementation_hitachi_HD44780.h'. m.) Split 'dogm_font_data_Marlin.h' into separate fonts and delete. (+dogm_font_data_6x9_marlin.h , +dogm_font_data_Marlin_symbols.h, -dogm_font_data_Marlin.h) n.) Do a bit of preprocessor magic to match displays - fonts and mappers in 'utf_mapper.h'. @@ -92,13 +93,13 @@ We have two different technologys for the displays: b.) Ether their is declared MAPPER_NON (-> c.) or an other mapper (-> d.) c.) Symbols outside the normal ASCII-range (32-128) are written as "\xxx" and point directly into the font of the hardware you declared in 'Configuration.h' This is one of the three fonts of the character based Hitachi displays (DISPLAY_CHARSET_HD44780_JAPAN, DISPLAY_CHARSET_HD44780_WEST, DISPLAY_CHARSET_HD44780_CYRILIC). - Even on the full graphic displays one of these will be used. + Even on the full graphic displays one of these will be used when SIMULATE_ROMFONT is defined. If you don't make use of the extended character set your file will look like 'language_en.h' and your language file will work on all the displays. If you make intensive use, your file will look like 'language_kana.h' and your language file will only work on one of displays. (in this case DISPLAY_CHARSET_HD44780_JAPAN) - Be careful with the characters 0x5c = '\', and 0x7b - 0x7f. These are not the same on all variants. + Be careful with the characters 0x5c = '\', and 0x7b - 0x7f. "{|}"These are not the same on all variants. MAPPER_NON is the fastest an least memory consuming variant. If you want to make use of more than a view symbols outside standard ASCII or want to improve the portability to more different types of displays use UTF8 input. That means define an other mapper. - d.) With a mapper different to MAPPER_NON UTF8 input is used. Instead of "\xe1" (on a display with Japanese font) or STR_ae simply use "?". When the string is read byte by byte , the "?" will expand to "\0xc3\0xa4" or "" will expand to "0xd0\0xaf" or "?" will expand to "\0xe3\0x83\0x9b" + d.) With a mapper different to MAPPER_NON UTF8 input is used. Instead of "\xe1" (on a display with Japanese font) or STR_ae simply use "ä". When the string is read byte by byte , the "ä" will expand to "\0xc3\0xa4" or "Я" will expand to "0xd0\0xaf" or "ホ" will expand to "\0xe3\0x83\0x9b" To limit the used memory we can't use all the possibilities UTF8 gives at the same time. We define a subset matching to the language or script we use. MAPPER_C2C3 correspondents good with west European languages the possible symbols are listed at (http://en.wikipedia.org/wiki/Latin-1_Supplement_(Unicode_block)) MAPPER_D0D1 correspondents well with the Cyrillic languages. See (http://en.wikipedia.org/wiki/Cyrillic_(Unicode_block)) @@ -106,20 +107,31 @@ We have two different technologys for the displays: The mapper functions will only catch the 'lead in' described in the mappers name. If the input they get does not match they'll put out a '?' or garbage. The last byte in the sequence ether points directly into a matching ISO10646 font or via a mapper_table into one of the HD44780 fonts. The mapper_tables do their best to find a similar symbol in the HD44780_fonts. For example replacing small letters with the matching capital letters. But they may fail to find something matching and will output a '?'. There are combinations of language and display what simply have no corresponding symbols - like Cyrillic on a Japanese display or visa versa - than the compiler will throw an error. - In short: Chose a Mapper working with the symbols you want to use. Use only symbols matching the mapper. On FULL graphic displays all will be fine, but check for daring replacements or question-marks in the output of character based displays. - If you get a lot of question-marks on the Hitachi based displays with your new translation, maybe creating a new language file with the format 'language_xx_utf8.h' is the way to go. + In short: Chose a Mapper working with the symbols you want to use. Use only symbols matching the mapper. On FULL graphic displays all will be fine, but check for daring replacements or question-marks in the output of character based displays by defining SIMULATE_ROMFONT and trying the different variants. + If you get a lot of question-marks on the Hitachi based displays with your new translation, maybe creating an additional language file with the format 'language_xx_utf8.h' is the way to go. + MAPPER_NON is the fastest and least memory consuming variant. Mappers together with a ISO10646_font are the second best choice regarding speed and memory consumption. Only a few more decisions are mad per character. Mappers together with the HD44780_fonts use about additional 128 bytes for the mapping_table. - e.) Creating a new language file is not a big thing. Just make a new file with the format 'language_xx.h' or maybe 'language.xx.utf8.h', define a mapper in there and translate some of the strings defined in language_en.h. You can drop the surrounding #ifndef #endif. You don't have to translate all the stings - the missing one will be added by language_en.h - in English - of cause. + e.) Creating a new language file is not a big thing. Just make a new file with the format 'language_xx.h' or maybe 'language.xx.utf8.h', define a mapper and a font in there and translate some of the strings defined in language_en.h. You can drop the surrounding #ifndef #endif. You don't have to translate all the stings - the missing one will be added by language_en.h - in English - of cause. f.) If you cant find a matching mapper things will be a bit more complex. With the Hitachi based displays you will not have big chance to make something useful unless you have one with a matching charset. For a full graphic display - lets explain with - let's say Greece. Find a matching charset. (http://en.wikipedia.org/wiki/Greek_and_Coptic) Provide a font containing the symbols in the right size. Normal ASCII in the lower 127 places, the upper with your selection. Write a mapper catching, in this case, 0xcd to 0xcf and add it to 'utf_mapper.h'. In case of a ISO10646 font we have a MAPPER_ONE_TO_ONE and don't have to make a table. - g.) If you discover enough useful symbols in one of the HD44780 fonts you can provide a mapping table. For example HD44780_WEST contains 'alpha', 'beta', 'pi', 'Sigma', 'omega' 'My' - what is not enough to make USEFUL table - i think. + g.) If you discover enough useful symbols in one of the HD44780 fonts you can provide a mapping table. For example HD44780_WEST contains 'alpha', 'beta', 'pi', 'Sigma', 'omega' 'My' - what is not enough to make USEFUL table - I think. h.) If you want to integrate an entirely new variant of a Hitachi based display. Add it in 'Configuration.h'. Define mapper tables in 'utf_mapper.h'. Maybe you need a new mapper function. + The length of the strings is limited. '17 chars' was crude rule of thumb. Obviously 17 is to long for the 16x2 displays. A more exact rule would be max_strlen = Displaywidth - 2 - strlen(value to display behind). This is a bit complicated. So try and count is my rule of thumb. + On the 16x2 displays the strings are cut at the end to fit on the display. So it's a good idea to make them differ early. ('Somverylongoptionname x' -> 'x Somverylongoptionname') + You'll find all translatable strings in 'language_en.h'. Please don't translate any strings from 'language.h', this may break the serial protocol. + ## User Instructions - Define your hardware and language in 'Configuration.h'. Done. - \ No newline at end of file + Define your hardware and the wanted language in 'Configuration.h'. + To find out what charset you harware is define language 'test' and compile. In the menu you will see two lines from the upper half of the charset. + * DISPLAY_CHARSET_HD44780_JAPAN locks like "バパヒビピフブプヘベペホボポマミ" + * DISPLAY_CHARSET_HD44780_WESTERN locks like "ÐÑÒÓÔÕÖ×ØÙÚÛÜÝÞß" + * DISPLAY_CHARSET_HD44780_CYRILIC locks like "РСТУФХЦЧШЩЪЫЬЭЮЯ" + + If you get an error about missing mappers during compilation - lie about your displays hardware font to see at lest some garbage, or select an other language. English works on all hardware. + diff --git a/Marlin/Configuration.h b/Marlin/Configuration.h index 96c307bcb..53f916b31 100644 --- a/Marlin/Configuration.h +++ b/Marlin/Configuration.h @@ -567,10 +567,11 @@ const bool Z_MAX_ENDSTOP_INVERTING = true; // set to true to invert the logic of // Define your display language below. Replace (en) with your language code and uncomment. // en, pl, fr, de, es, ru, it, pt, pt-br, fi, an, nl, ca, eu, kana, kana_utf8, kanji, test // See also language.h -//#define LANGUAGE_INCLUDE GENERATE_LANGUAGE_INCLUDE(en) +#define LANGUAGE_INCLUDE GENERATE_LANGUAGE_INCLUDE(en) -// Chose ONE of the next three charsets. This has to match your hardware. In case of a full graphic display chose that one best fitting to your language. -// to find out what type you have - compile with language_test.h - upload - click to get the menu. You'll see two typical lines from the upper half of the charset. +// Chose ONE of the next three charsets. This has to match your hardware. In case of a full graphic display this information is not important. +// To find out what type you have - compile with (test) - upload - click to get the menu. You'll see two typical lines from the upper half of the charset. +// Se also documentation/LCDLanguageFont.md #define DISPLAY_CHARSET_HD44780_JAPAN // this is the most common hardware //#define DISPLAY_CHARSET_HD44780_WESTERN //#define DISPLAY_CHARSET_HD44780_CYRILIC diff --git a/Marlin/dogm_lcd_implementation.h b/Marlin/dogm_lcd_implementation.h index 171b42733..ab61751a7 100644 --- a/Marlin/dogm_lcd_implementation.h +++ b/Marlin/dogm_lcd_implementation.h @@ -35,10 +35,10 @@ #include "ultralcd.h" #include "ultralcd_st7920_u8glib_rrd.h" #include "configuration.h" -#include "utf_mapper.h" + #include -#include "dogm_font_data_6x9_marlin.h" // Height of 'A' is only 5 pixel. +#include "dogm_font_data_6x9_marlin.h" // Height of 'A' is only 6 pixel. #include "dogm_font_data_Marlin_symbols.h" // The Marlin special symbols #define FONT_STATUSMENU_NAME u8g_font_6x9 // we don't have a small font for Cyrillic, Kana or Kanji @@ -50,38 +50,38 @@ #define USE_BIG_EDIT_FONT #endif -#if defined( MAPPER_C2C3 ) - #include // System font. This is ISO10646-1 - #define FONT_MENU_NAME u8g_font_6x10 - -#elif defined( MAPPER_D0D1 ) - #include "dogm_font_data_ISO10646_5_Cyrillic.h" - #define FONT_MENU_NAME ISO10646_5_Cyrillic_5x7 - -#elif defined( MAPPER_E382E383 ) - #include "dogm_font_data_ISO10646_Kana.h" - #define FONT_MENU_NAME ISO10646_Kana_5x7 - -#elif defined( DISPLAY_CHARSET_KANJI ) && defined( MAPPER_NON ) - #include "dogm_font_data_6x10_marlin_Kanji.h" - #define FONT_MENU_NAME u8g_font_6x10_marlin - -#elif defined( DISPLAY_CHARSET_HD44780_JAPAN ) - #include "dogm_font_data_HD44780_J.h" - #define FONT_MENU_NAME HD44780_J_5x7 - -#elif defined( DISPLAY_CHARSET_HD44780_WESTERN ) - #include "dogm_font_data_HD44780_W.h" - #define FONT_MENU_NAME HD44780_W_5x7 - -#elif defined( DISPLAY_CHARSET_HD44780_CYRILIC ) - #include "dogm_font_data_HD44780_C.h" - #define FONT_MENU_NAME HD44780_C_5x7 - -#else // #if defined( MAPPER_C2C3 ) // fall-back - #include // system font - #define FONT_MENU_NAME u8g_font_6x10 -#endif +#ifndef SIMULATE_ROMFONT + #if defined( DISPLAY_CHARSET_ISO10646_1 ) + #include // System font. + #define FONT_MENU_NAME u8g_font_6x10 + #elif defined( DISPLAY_CHARSET_ISO10646_5 ) + #include "dogm_font_data_ISO10646_5_Cyrillic.h" + #define FONT_MENU_NAME ISO10646_5_Cyrillic_5x7 + #elif defined( DISPLAY_CHARSET_ISO10646_KANA ) + #include "dogm_font_data_ISO10646_Kana.h" + #define FONT_MENU_NAME ISO10646_Kana_5x7 + #elif defined( DISPLAY_CHARSET_KANJI ) + #include "dogm_font_data_6x10_marlin_Kanji.h" + #define FONT_MENU_NAME u8g_font_6x10_marlin + #else // fall-back + #include // system font + #define FONT_MENU_NAME u8g_font_6x10 + #endif +#else // SIMULATE_ROMFONT + #if defined( DISPLAY_CHARSET_HD44780_JAPAN ) + #include "dogm_font_data_HD44780_J.h" + #define FONT_MENU_NAME HD44780_J_5x7 + #elif defined( DISPLAY_CHARSET_HD44780_WESTERN ) + #include "dogm_font_data_HD44780_W.h" + #define FONT_MENU_NAME HD44780_W_5x7 + #elif defined( DISPLAY_CHARSET_HD44780_CYRILIC ) + #include "dogm_font_data_HD44780_C.h" + #define FONT_MENU_NAME HD44780_C_5x7 + #else // fall-back + #include // system font + #define FONT_MENU_NAME u8g_font_6x10 + #endif +#endif // SIMULATE_ROMFONT #define FONT_STATUSMENU 1 #define FONT_SPECIAL 2 @@ -138,6 +138,8 @@ U8GLIB_NHD_C12864 u8g(DOGLCD_CS, DOGLCD_A0); U8GLIB_DOGM128 u8g(DOGLCD_CS, DOGLCD_A0); // HW-SPI Com: CS, A0 #endif +#include "utf_mapper.h" + char currentfont = 0; static void lcd_setFont(char font_nr) { diff --git a/Marlin/language.h b/Marlin/language.h index 330bb3c91..b4c6f3aba 100644 --- a/Marlin/language.h +++ b/Marlin/language.h @@ -11,6 +11,7 @@ // // ==> ALWAYS TRY TO COMPILE MARLIN WITH/WITHOUT "ULTIPANEL" / "ULTRALCD" / "SDSUPPORT" #define IN "Configuration.h" // ==> ALSO TRY ALL AVAILABLE LANGUAGE OPTIONS +// Se also documentation/LCDLanguageFont.md // Languages // en English @@ -201,6 +202,11 @@ #define MSG_MAXTEMP_BED_OFF "Heated bed" MSG_SWITCHED_OFF_MAX // LCD Menu Messages + +#if !(defined( DISPLAY_CHARSET_HD44780_JAPAN ) || defined( DISPLAY_CHARSET_HD44780_WESTERN ) || defined( DISPLAY_CHARSET_HD44780_CYRILIC )) + #define DISPLAY_CHARSET_HD44780_JAPAN +#endif + #include LANGUAGE_INCLUDE #include "language_en.h" diff --git a/Marlin/language_an.h b/Marlin/language_an.h index 6155d5742..aef304075 100644 --- a/Marlin/language_an.h +++ b/Marlin/language_an.h @@ -2,13 +2,16 @@ * Aragonese * * LCD Menu Messages - * Please note these are limited to 17 characters! + * Se also documentation/LCDLanguageFont.md * */ #ifndef LANGUAGE_AN_H #define LANGUAGE_AN_H #define MAPPER_NON +// Define SIMULATE_ROMFONT to see what is seen on the character based display defined in Configuration.h +//#define SIMULATE_ROMFONT +#define DISPLAY_CHARSET_ISO10646_1 #define WELCOME_MSG MACHINE_NAME " parada." #define MSG_SD_INSERTED "Tarcheta colocada" diff --git a/Marlin/language_ca.h b/Marlin/language_ca.h index 2627438ec..8f00f8b7d 100644 --- a/Marlin/language_ca.h +++ b/Marlin/language_ca.h @@ -2,7 +2,7 @@ * Catalan * * LCD Menu Messages - * Please note these are limited to 17 characters! + * Se also documentation/LCDLanguageFont.md * */ #ifndef LANGUAGE_CA_H @@ -10,6 +10,9 @@ //#define MAPPER_NON #define MAPPER_C2C3 // because of "ó" +// Define SIMULATE_ROMFONT to see what is seen on the character based display defined in Configuration.h +//#define SIMULATE_ROMFONT +#define DISPLAY_CHARSET_ISO10646_1 #define WELCOME_MSG MACHINE_NAME " preparada." #define MSG_SD_INSERTED "SD detectada." diff --git a/Marlin/language_de.h b/Marlin/language_de.h index af7bdf93c..2487ba93a 100644 --- a/Marlin/language_de.h +++ b/Marlin/language_de.h @@ -2,13 +2,16 @@ * German * * LCD Menu Messages - * Please note these are limited to 17 characters! + * Se also documentation/LCDLanguageFont.md * */ #ifndef LANGUAGE_DE_H #define LANGUAGE_DE_H #define MAPPER_C2C3 +// Define SIMULATE_ROMFONT to see what is seen on the character based display defined in Configuration.h +//#define SIMULATE_ROMFONT +#define DISPLAY_CHARSET_ISO10646_1 #define WELCOME_MSG MACHINE_NAME " Bereit." #define MSG_SD_INSERTED "SDKarte erkannt." diff --git a/Marlin/language_en.h b/Marlin/language_en.h index 42e9f0b1c..51c575aae 100644 --- a/Marlin/language_en.h +++ b/Marlin/language_en.h @@ -2,16 +2,22 @@ * English * * LCD Menu Messages - * Please note these are limited to 17 characters! + * Se also documentation/LCDLanguageFont.md * */ #ifndef LANGUAGE_EN_H #define LANGUAGE_EN_H -#if !(defined(MAPPER_NON) || defined(MAPPER_C2C3) || defined(MAPPER_D0D1_MOD) || defined(MAPPER_E382E383)) +#if !( defined(MAPPER_NON)|| defined(MAPPER_C2C3)|| defined(MAPPER_D0D1)|| defined(MAPPER_D0D1_MOD)|| defined(MAPPER_E382E383) ) #define MAPPER_NON // For direct asci codes #endif +//#define SIMULATE_ROMFONT //Comment in to see what is seen on the character based displays +#if !( defined(SIMULATE_ROMFONT)|| defined(DISPLAY_CHARSET_ISO10646_1)|| defined(DISPLAY_CHARSET_ISO10646_5)|| defined(DISPLAY_CHARSET_ISO10646_KANA)|| defined(DISPLAY_CHARSET_KANJI) ) + #define DISPLAY_CHARSET_ISO10646_1 // use the better font on full graphic displays. +#endif + + #ifndef WELCOME_MSG #define WELCOME_MSG MACHINE_NAME " ready." #endif diff --git a/Marlin/language_es.h b/Marlin/language_es.h index d6a38d3ce..1602c3c1c 100644 --- a/Marlin/language_es.h +++ b/Marlin/language_es.h @@ -2,13 +2,16 @@ * Spanish * * LCD Menu Messages - * Please note these are limited to 17 characters! + * Se also documentation/LCDLanguageFont.md * */ #ifndef LANGUAGE_ES_H #define LANGUAGE_ES_H #define MAPPER_NON +// Define SIMULATE_ROMFONT to see what is seen on the character based display defined in Configuration.h +//#define SIMULATE_ROMFONT +#define DISPLAY_CHARSET_ISO10646_1 #define WELCOME_MSG MACHINE_NAME " lista." #define MSG_SD_INSERTED "Tarjeta colocada" diff --git a/Marlin/language_eu.h b/Marlin/language_eu.h index f4857ccfb..9bce0a7c1 100644 --- a/Marlin/language_eu.h +++ b/Marlin/language_eu.h @@ -2,13 +2,16 @@ * Basque-Euskera * * LCD Menu Messages - * Please note these are limited to 17 characters! + * Se also documentation/LCDLanguageFont.md * */ #ifndef LANGUAGE_EU_H #define LANGUAGE_EU_H #define MAPPER_NON +// Define SIMULATE_ROMFONT to see what is seen on the character based display defined in Configuration.h +//#define SIMULATE_ROMFONT +#define DISPLAY_CHARSET_ISO10646_1 #define WELCOME_MSG MACHINE_NAME " prest." #define MSG_SD_INSERTED "Txartela sartuta" diff --git a/Marlin/language_fi.h b/Marlin/language_fi.h index d84f1b28a..711f09639 100644 --- a/Marlin/language_fi.h +++ b/Marlin/language_fi.h @@ -2,13 +2,16 @@ * Finnish * * LCD Menu Messages - * Please note these are limited to 17 characters! + * Se also documentation/LCDLanguageFont.md * */ #ifndef LANGUAGE_FI_H #define LANGUAGE_FI_H #define MAPPER_C2C3 +// Define SIMULATE_ROMFONT to see what is seen on the character based display defined in Configuration.h +//#define SIMULATE_ROMFONT +#define DISPLAY_CHARSET_ISO10646_1 #define WELCOME_MSG MACHINE_NAME " valmis." #define MSG_SD_INSERTED "Kortti asetettu" diff --git a/Marlin/language_fr.h b/Marlin/language_fr.h index 4c443f90d..7e1194d7b 100644 --- a/Marlin/language_fr.h +++ b/Marlin/language_fr.h @@ -2,13 +2,17 @@ * French * * LCD Menu Messages - * Please note these are limited to 17 characters! + * Se also documentation/LCDLanguageFont.md * */ #ifndef LANGUAGE_FR_H #define LANGUAGE_FR_H #define MAPPER_NON +// Define SIMULATE_ROMFONT to see what is seen on the character based display defined in Configuration.h +//#define SIMULATE_ROMFONT +#define DISPLAY_CHARSET_ISO10646_1 + #define WELCOME_MSG MACHINE_NAME " prete." #define MSG_SD_INSERTED "Carte inseree" diff --git a/Marlin/language_it.h b/Marlin/language_it.h index 0cb0dc94d..5b2709faf 100644 --- a/Marlin/language_it.h +++ b/Marlin/language_it.h @@ -2,13 +2,16 @@ * Italian * * LCD Menu Messages - * Please note these are limited to 17 characters! + * Se also documentation/LCDLanguageFont.md * */ #ifndef LANGUAGE_IT_H #define LANGUAGE_IT_H #define MAPPER_NON +// Define SIMULATE_ROMFONT to see what is seen on the character based display defined in Configuration.h +//#define SIMULATE_ROMFONT +#define DISPLAY_CHARSET_ISO10646_1 #define WELCOME_MSG MACHINE_NAME " pronto." #define MSG_SD_INSERTED "SD Card inserita" diff --git a/Marlin/language_kana.h b/Marlin/language_kana.h index 8c8ecdb87..5810fa11d 100644 --- a/Marlin/language_kana.h +++ b/Marlin/language_kana.h @@ -2,7 +2,7 @@ * Japanese (Kana) * * LCD Menu Messages - * Please note these are limited to 17 characters! + * Se also documentation/LCDLanguageFont.md * */ @@ -10,6 +10,9 @@ #define LANGUAGE_KANA_H #define MAPPER_NON +// Define SIMULATE_ROMFONT to see what is seen on the character based display defined in Configuration.h +#define SIMULATE_ROMFONT +#define DISPLAY_CHARSET_ISO10646_KANA // 片仮名表示定義 #define WELCOME_MSG MACHINE_NAME " ready." diff --git a/Marlin/language_kana_utf8.h b/Marlin/language_kana_utf8.h index d364a0332..5501475ea 100644 --- a/Marlin/language_kana_utf8.h +++ b/Marlin/language_kana_utf8.h @@ -2,7 +2,7 @@ * Japanese (Kana UTF8 version) * * LCD Menu Messages - * Please note these are limited to 17 characters! + * Se also documentation/LCDLanguageFont.md * */ @@ -10,6 +10,9 @@ #define LANGUAGE_KANA_UTF_H #define MAPPER_E382E383 +// Define SIMULATE_ROMFONT to see what is seen on the character based display defined in Configuration.h +//#define SIMULATE_ROMFONT +#define DISPLAY_CHARSET_ISO10646_KANA // This is very crude replacement of the codes used in language_kana.h from somebody who really does not know what he is doing. // Just to show the potential benefit of unicode. diff --git a/Marlin/language_kanji.h b/Marlin/language_kanji.h index 15b8359ab..8c98b6a05 100644 --- a/Marlin/language_kanji.h +++ b/Marlin/language_kanji.h @@ -2,7 +2,7 @@ * Japanese (Kanji) * * LCD Menu Messages - * Please note these are limited to 17 characters! + * Se also documentation/LCDLanguageFont.md * */ #include "Configuration.h" diff --git a/Marlin/language_nl.h b/Marlin/language_nl.h index f691fe6fb..81eef72bb 100644 --- a/Marlin/language_nl.h +++ b/Marlin/language_nl.h @@ -2,13 +2,16 @@ * Dutch * * LCD Menu Messages - * Please note these are limited to 17 characters! + * Se also documentation/LCDLanguageFont.md * */ #ifndef LANGUAGE_NL_H #define LANGUAGE_NL_H #define MAPPER_NON +// Define SIMULATE_ROMFONT to see what is seen on the character based display defined in Configuration.h +//#define SIMULATE_ROMFONT +#define DISPLAY_CHARSET_ISO10646_1 #define WELCOME_MSG MACHINE_NAME " gereed." #define MSG_SD_INSERTED "Kaart ingestoken" diff --git a/Marlin/language_pl.h b/Marlin/language_pl.h index e8d74100a..2d5643024 100644 --- a/Marlin/language_pl.h +++ b/Marlin/language_pl.h @@ -2,13 +2,16 @@ * Polish * * LCD Menu Messages - * Please note these are limited to 17 characters! + * Se also documentation/LCDLanguageFont.md * */ #ifndef LANGUAGE_PL_H #define LANGUAGE_PL_H #define MAPPER_NON +// Define SIMULATE_ROMFONT to see what is seen on the character based display defined in Configuration.h +//#define SIMULATE_ROMFONT +#define DISPLAY_CHARSET_ISO10646_1 #define WELCOME_MSG MACHINE_NAME " gotowy." #define MSG_SD_INSERTED "Karta wlozona" diff --git a/Marlin/language_pt-br.h b/Marlin/language_pt-br.h index f15627a05..734272a29 100644 --- a/Marlin/language_pt-br.h +++ b/Marlin/language_pt-br.h @@ -2,13 +2,16 @@ * Portuguese (Brazil) * * LCD Menu Messages - * Please note these are limited to 17 characters! + * Se also documentation/LCDLanguageFont.md * */ #ifndef LANGUAGE_PT_BR_H #define LANGUAGE_PT_BR_H #define MAPPER_NON +// Define SIMULATE_ROMFONT to see what is seen on the character based display defined in Configuration.h +//#define SIMULATE_ROMFONT +#define DISPLAY_CHARSET_ISO10646_1 #define WELCOME_MSG MACHINE_NAME " pronto." #define MSG_SD_INSERTED "Cartao inserido" diff --git a/Marlin/language_pt.h b/Marlin/language_pt.h index 17e4c3307..08274e112 100644 --- a/Marlin/language_pt.h +++ b/Marlin/language_pt.h @@ -2,13 +2,16 @@ * Portuguese * * LCD Menu Messages - * Please note these are limited to 17 characters! + * Se also documentation/LCDLanguageFont.md * */ #ifndef LANGUAGE_PT_H #define LANGUAGE_PT_H #define MAPPER_NON +// Define SIMULATE_ROMFONT to see what is seen on the character based display defined in Configuration.h +//#define SIMULATE_ROMFONT +#define DISPLAY_CHARSET_ISO10646_1 #define WELCOME_MSG MACHINE_NAME " pronto." #define MSG_SD_INSERTED "Cartao inserido" diff --git a/Marlin/language_ru.h b/Marlin/language_ru.h index 42c974fa1..3e3359855 100644 --- a/Marlin/language_ru.h +++ b/Marlin/language_ru.h @@ -2,13 +2,16 @@ * Russian * * LCD Menu Messages - * Please note these are limited to 17 characters! + * Se also documentation/LCDLanguageFont.md * */ #ifndef LANGUAGE_RU_H #define LANGUAGE_RU_H -#define MAPPER_D0D1 // For Cyrillic +#define MAPPER_D0D1 // For Cyrillic +// Define SIMULATE_ROMFONT to see what is seen on the character based display defined in Configuration.h +//#define SIMULATE_ROMFONT +#define DISPLAY_CHARSET_ISO10646_5 #define WELCOME_MSG MACHINE_NAME " Готов." #define MSG_SD_INSERTED "Карта вставлена" diff --git a/Marlin/language_test.h b/Marlin/language_test.h index b58da76f6..a2ba43fae 100644 --- a/Marlin/language_test.h +++ b/Marlin/language_test.h @@ -2,7 +2,7 @@ * TEST * * LCD Menu Messages - * Please note these are limited to 17 characters! + * Se also documentation/LCDLanguageFont.md * */ #ifndef LANGUAGE_TEST_H @@ -10,12 +10,12 @@ // Select ONE of the following Mappers. // They decide what to do with a symbol in the area of [0x80:0xFF]. They take a symbol of this language file and make them point -// into an array with 128 cells, where they find the place of the symbol in the font in use. +// into an array with 128 cells, where they'll find the place of the symbol of the font in use. // // a.)For ASCII coded Language_xx.h files like (en) there are no occurrences of symbols above 0x7F so no mapper is needed. -// If such a symbol appers it is mapped directly into the font. This is the case for the language files we used until now, with all the STR_XX or +// If such a symbol appears it is mapped directly into the font. This is the case for the language files we used until now, with all the STR_XX or // "\xxx" symbols. All Symbols are only one byte long. -// b.) For Unicoded Language_xx.h files (currently ru and de) the non ASCII [0x00-0x7F] symbols are represented by more then one byte. +// b.) For Unicoded Language_xx.h files (currently ru, de and kana_utf8 ) the non ASCII [0x00-0x7F] symbols are represented by more then one byte. // In the case of two bytes the first is pointing to a 'codepage' and the second to a place in the codepage. These codepages contain 64 symbols. // So two of them can be mapped. For most of the European languages the necessary symbols are contained in the pages C2 and C3. Cyrillic uses D0 // and D1. @@ -25,14 +25,22 @@ // impossible to have a close to direct mapping but will need giant conversion tables and fonts (we don't want to have in a embedded system). // d.) So for Kanji we use a very special and selected subset of symbols and the direct mapping like in a). -#define MAPPER_NON // For direct asci codes ( until now all languages except ru, de, ... ) +#define MAPPER_NON // For direct asci codes ( until now all languages except ru, de, fi, kana_utf8, ... ) //#define MAPPER_C2C3 // For most European languages when language file is in utf8 //#define MAPPER_D0D1 // For Cyrillic -////#define MAPPER_D0D1_MOD // For Cyrillic on HD44780_CYRILIC (will save 32 byte in the mapper but adds some more decisions) //#define MAPPER_E382E383 // For Katakana +// Define SIMULATE_ROMFONT to see what is seen on the character based display defined in Configuration.h +//#define SIMULATE_ROMFONT -// next 4 lines select variants in this file only +// Select the better font for full graphic displays. +//#define DISPLAY_CHARSET_ISO10646_1 +//#define DISPLAY_CHARSET_ISO10646_5 +//#define DISPLAY_CHARSET_ISO10646_KANA +//#define DISPLAY_CHARSET_KANJI + + +// next 5 lines select variants in this file only #define DISPLAYTEST //#define WEST //#define CYRIL @@ -96,8 +104,8 @@ #define WELCOME_MSG "Language TEST" #define MSG_WATCH "Display test" - #define MSG_PREPARE STRG_OKTAL_c - #define MSG_CONTROL STRG_OKTAL_d + #define MSG_PREPARE STRG_OKTAL_b + #define MSG_CONTROL STRG_OKTAL_c #endif #ifdef WEST diff --git a/Marlin/scripts/Fonts/bdf2u8g.exe b/Marlin/scripts/Fonts/bdf2u8g.exe index ab4e3f96dd34f1378d0ca929f86570ad32c10f80..1e51b26567d78d2ba1b5eda6942a18561846dee2 100644 GIT binary patch literal 56515 zcmeHw3w%_?z5hA88#q8nf&`5gbcLW%AtV}J3Uwh_gc>9Qv7p!`B%6mWNt*2Puz+Yl zi7Oh^R`0#G5V5_qS6bV8TPm~-j|y6AsntrAwrNGXH2hmyQ=3+9^Z$Nl=Dc!(t@-zJ z|M%g6lbQLw=Qr;;XV1*PxlQwHnijy_+pB4N5b_F%zwiHNBhVQaJ)5CDGvo&s@6k(t zaPi{Wy5?YGQ$tNt#mZo1MSXokJh&nnY)aGz>*|9g3l;@eHdICPhYuf`t3;QDHLX<7 z&>lbV+Kt+MnzjkXbZUe3VY=^J?Me_W#NFxBHlBkp3wIfATF1Cg+N~o>`{jig{;zvL z7x~h(prj=Od2p#fCYJlP9-CRhKFHsVel4dz`U<~xs6V)Z<;SCI;)v%J;13OAUi;Xw zTq|3iUsVyW0ICeP_=7xaQ<$)?khZ)dzey4<9t`+$+y?GxxE)tWD+o<0l7RS7gpIh< zaffg_F4E<%Xl^EG@z0@fqXX%PZlvBisaN=LISOwO2udA9h(caRe(}P^gbH6Zf{yuM z**Y#k7mo?OLBcmGI>BiZl5SF=%!r_CQ*<}kG>nC`tl5*UoGyS{&PA{TbTnXz09k(o zT~VP(ucTcapkrCkKaNY#O`a?uLFV%)=;-ITg9uSUH)W~-=J9W*vTvOLS$_oGR9Q%K zSstfB$MV=n1au)I zYcFdPDrYChlvWgLJ4?U|WFT3b)f&i6Wtb!qRzTQaCMq@wD zkg9t}g-{bxxBmwyP!KM>&&FTx#Y(=W{(7fHQ|fQ&nW}o5d<5kAfVsV7=nkA!%I;!H$NXQ1n4q~XjURFC+$=vqS_KM z1axHSJ^K8?Jld$I{S>ECBX^u39!>p`Y*C&(V?lh9#r)7Sl zgRO*?RKXI+qht15j#3MEZ!Ob>u;~ZlBZ&bKG6_Sq)B}XeWvGu!4x(!Tu=Z&U2?3q+))CwOO8>QN9u;+s-pnk}Z~RQBQU8M?vLnvFcgU~%e;;F0vR zrA&z0aG@YemY=!nK=A9cwJpBh@R`(fDgCEVo(!K!BjP#c^GxbC%An24^;t@pX=Y2$ zMg5C>8|?!I_al<6%_*|4{X>P#C%2uVA}4hfpw9dYBfBQ{=P*MG{1;R2M@@mUIf{PSEXu~KKn{($dC1ENEQXfOlgK{?Yrq;tC!1qVb1X7CxltaZOm zhO<}(laNl+&~UB@XN`vm8#i~X9Xxk9Rwlinq?Ahy9$y@>{3jcAm(tYH7D7Hmn>79X zwj#}GS)Z=0DMa2;I;2Bae2JYxSIF^9PD*5V_^t79S)dJVScrhDEl#t~a`Z4RbS6{f z=`fs{AVJjX!)fUcs=`h?jb4t|;k0RJ1u~YhU_lF3u-&A~vtXSTT>yQ{mf|8?{nfBa+3c<)uf|8?{xAsFYNN_N+lc3}%W>x9fFjPc#5|kXp zoGTqb2pt3^N6`^V2M|IBK~Qe%07B>>C^?F5YB$V$FtU@Ngj;9Bfqlf(j zCZ+A15Vv#$IRf8=bjzWFTRx$BL5w3kEUm6dW|JC|EbnPOy1&z>^N(n|X(1?=0}-10 z$PGX14fou&zUMIbHpqtZaoWAEJ#S-3OkOwd#-dSKNR#!WJDJUPW}>BMR${2g;m%wn z6|B&N9YG-}SPfvJ1cE40lo_eXA_|j{odhWa`2>OyflyNN66Y%tx66e%Y0xe2Ly{cD z3f)craS*q)3>REI)xtWzE5|DqyaxP$5>Rw}LQD z&bL!TU{W%CVkhgmFbETm24N4UgCO4iM_9^wtI`iLO=^|ClWDdsm2O~~wOyqnf*yWW z=>LY28L(=7x#N4;^{B@mdnk_xUH(Z|_Bf8M^vmkEB~2lJ24;7PXKh%3Kx$ zqaI23_mMQxA!#Zl(NUZO1!U$sd_&}HCNWXUDv|4)7yHQhK9=HU%lIAQLeBoqz?K8H z996IG{R8S1vnkOubI4JJyPY_ex?+Vf7H$D>cJ)in6qSSBTx<9cDjg%`9df*Aoxe}G zq&2)JIf|-U%byYEb1`y`irsOiksQNn+Lg99sG%{7VF#JeK0QlIU5QMjG1j^+H#a%| z5DGV#Ebl=1j!w?shg43od=FCD$@$NSf?tMiBQBkjT`8Bw?~aBeR9}_(Ahts=)9l1w zt!w__@Np5jJXzl99Dt7NN5udn7nSHmmi`{IxA`Y}!^c$t6{ZE=q=vsZ#y)X_TBxt}91A z=Hqi<(&G7hxLI>W_>~`ZZrT6i=rLQyjs44zc}FjIO}I1j!E50w;es)ofQI^U!Sx@} zw6>N*>u&i(L`(`Wl3TNaQcN>Bf?x&`HvV+9rE_p=_;jBMLbs!QjwZvWTYn5Y-)lYA z(y3zxtk&M=V9KD%q-Wii#EP!vP}VK|DeN&7_SgyyXNCCt6|$aB5BICkTXm2#wUKdh zmnd#AF*=F8IxSh=?KGgr%JJ6pv*EU2dfq>ifwj-pCAtf(A5&GlBQjS{HRpTN zXik~#%paC((wr=)cG_{qVTW94b+7A?CUH+kSaM+9=hcEJ&^1PwFqcFBPRvwL9nO`I zouW_YpUoY2zTP#Zt?MemEl5vF(h2RH2hH7S&4%Xg6#X~5wa`vE%!oez&O==nwsn0Z zH5Q9|(aDB(im{F2=L${i!EmK6l#-_jBcS=ku8AfpE>V}IIw+-I&D?9D1z>#MT(hyU zw5&I@wW^-4=OWNdGzvY_!^S#=ji|y(Hvu=8?F*%9wy$ok>l_nsyS8P11MRE3Z~J1$ z)s?n~8FZGuSpw^nB*N*bM&oZMqY`xQvp@Dn+|f1dIEYH6CaWxs8g#c!~t zfPagj))NJ(4XA}m_sPp(n^J#r2;!ouam!;ahKT^H#kb&X?sCHbP@ckH1nAeWTeBRk zQAFS*_Br}dEQyf+@A>&2yu&~EQIEHLe6S2G1bGT&|q5D zck3IT>J6W6S$|sJ@XsylPo>>C^+4uV%1^cDBHp@x|H+H=BR_)v zGyNJt;*Hy`K?3Ri(n^iQTm$b$qY~YXQ z@?a3!U`AJQOOG!;uBFExpU^cGEdY-y@Em3o@_!jpcvhgL%9;8IQdcl_9aF=R8pqUh zq}tf^u!RYWyE7kLi%fukPn}XZAb^8KZ5Q~{nGco$uX1Fhj-s`tE;J!%M7gN{^v~_T z5%poybC^k|5-PC|iS`0?2CONas7I+JFdWKntPF9E6-1Yi`nPNi1c?h%zEcuOD3O>k zr9K1X$pqw(>lO!B!sPnA5~;XCXy~csLAOJ zWcjK4K*sD{3Db6Rf|VTgBz$MiMMYCM|F^xpCtud3iS-UCFOL)%J3m!IWt`)su4asT z4JX?bL&Cw(E*U1KMv|f4qBt;g7q_y?n~W5Da~dZ|qe3?Vrrk!7aX0}0Z?8t$6fv&+X|XzKI`G!zUK zEr)XDREJNF#B7sB0->^EAS*jrA()0N%IVF7yg+V*~;s1z!?9Bq+PJBerm4|-HJs;E{A%elY9OV|ev zW&S2a+u2E}$?cxEIE12}sPrzTS@~4@F{W7sReB54tcWVTM&Qv(Hg{lY!kr$4hyc-* z)y^#*1(^>Byh5W=vmEisj`(Gc_!z|D1jU^xQdugcJLvv+!j^l|5&xMZ{v${Hdx)EU zNA8cI-_H7#~D>jM!WubYtgz!#$$FP;%)a^2A#xtgfM=%tXAM*6i;w zo_HGwk$B?QjL|59Q)c3clZ_;wRHT|~T626wfmeAR`V}uIlw+I6v1dL-*a4h#;V5| zT@^xQ5XNRw*BCa* zZW45g&H|5+q#h)qk#Tao7@J+fcFU@`t#2P*b#UnOxrIGVVHZOfs|FLQARg&tlRlf3 zUnf_W5{x=_4AGWD%gmL0dl8(3HhqDJU?qiQd*>swFlP(wWQd_d&D+_9@QJ_VFrPln z5!6XGezk%rQjq(!857O5eNe$d_i0y$&zR7msXNejI7X%ur}1bbH4_iPkjDwgKEpg+ zhN1^YI;h~I89_RS9S#;){yVQg8{5PD`bB=z#cMcxZ{P%ht1#~rx=xOTXOS6^S$4wA zXX6ooQsB2daHHfVqz;3w>nEU0kn&eZ^`ZRh5J8!j`Yb7*0%bEP z_joB^k(9ZqW>Ve_%0;AnKvIrTKBM+8Ny=bq9&jhiVIGKAkhsE2yj~KIPK_pUo+OTv zxX4RfCW&)Wzr%d{SW0EY|M&E&uNSt8eqW8-7{%Ml$eOreT&3Z_6Fj zr@xapCP{T1M_=6vBLX;Md(tD^T3Euyq?x_Foa==Gn-wg zAMoSo)W5)iaPDZl#HajPz$%n_81U3*@JGEUXT49h3=&FP4?=t{#bZZV)H(9UbIV$P zg7J27>knIFxl2-yf*r3u(#6k$3~Hve^aK)DfW!cCfG-YSL;aAL1alIsNid>QKd98U z^n~I^!C0_0hE^AobCHnJ33zTRD#28tCyVkOqQRQ^>5|+Fp_1W6siSFd^t#-OwDtqC-4zer;XJ!`8>tN%02t7u1Tl*5!6ja;62W7L^v$!Ut zP2``Jp23IHh(%f9HITEMe-6#HW(O zmm#)yIg`(4Zu%CGdr6rrHpEi#I*4sKn10uL1ZK9h0H67dMMknYkQ~fNl9pFmuys5iv41J%b2)9ONbs0#K4UfM}_G=nRD(DY!X5xhU|h05Dtc76KpQ zU;oIKg9f-qZ^fPB2BxHLdKo1dL`mkNB=cGhO*q&lZ63M#<;0hh#duL9bJI2OXIFdX zH_?lPv}$Dhn?G4Q=&l#Ah0=T33*YiV)m^_KO8*NqR$HHnc%B#%lt;xrk69n z@dvQH#MfF{{~)QsN#;fHRP>OQPB zogGN~+%mY4C43QTa&=qpQ32Un7D$Eyt)qy=bm3&nq4akSs`p=Wl4G(%DF63*yvT#3;t(ZCm zoC>~!g6{3Q&-AY_h&7E9HMp>_n|>@YqU(CopT_i`#xH6; zkeqFRn}s3NjshE$Dq+dFM(fAK(6<{IGHHH~IB2?F2k%Z{|Iw~D)OgBKuA~Wroj-o7 zIi!mEAZ&%ES`h(RqEpE`oJPO$N^Mt?zlZ*WK-9KNC7S;1PhR|=Q$Ez(u7^$Is+5Q$ zso$VlcWpE4aPRmcj0J6Nz2g_FaE1z}sc^0epH$&S6|Pg^ause-;bSUnRAGqD$G)0whAYx zFi(X673QiiU4^4nsHreVgz{bF)X!d)GwqRReP2cVd5*@ctv%OTBYK&);>O=V@IIa0Oy%87;fRk4^B zi8MuP>YC%xrbsn@#}|#%)mJxYg7CJ9g;z#FObO_yn7gC^KRKlU;YXxU}jiWO^uG*`09Rk7|}K53{X3Up?$Kr3EQwshgV>*g-j<}A2jv9@U5&0#HkL-B%=c{g0A z$#N5z*$c{VAZ+%6CED!SxaTdNKdTI+CB<`RE%esa8Nt~lb0YI+Es4wx3-L`WwACxL zhD1D4-59(Wd&=ddr7(S{77Wg5sE^m9eR&NVX(O4I+hy`Z_=Zb0% zc-4g9rG=L|(t@!fR+)&=Ey4K}Yl1gb#1g32t7neCvMN|B{;m;!*NVSYGEpT{@DN(H zK)^W+S=Xg;!PyOodeKN%G^`2oI*UxQfT!4D2YyJb>=2CN&snWd{AG!zsPGD?rCmX3 zanv#rl)>N(7v zNz~QHr$yo@EwrXvgXPn%i?H%U7KMu!&s%Uq-q`WYV=qH3{}jtaTYn9tpx;7|L?P&y z(YwGF)x|*is%R5>@8GJ!{DMOGZ+vs`mWi=oV?|B$R>TrktU1_RTUQ+?a8WSP*cfe^ zXaQE>hubxE^~6Qd9AMTh6RVYuTZO{vx>!_1Sk;24h>eLjVM8^m=WME|M}H}Mh@o0t zJt)v4g6-1r&6f_ZMeAI#Hje6wZnvVUswvvs930;$>r;9C?ez_->w}HW(L_~4uqhgA zsH}+BH2~7o5O1h#hy~%pW&&V53oRHtJI@OA@y&I2h>VH?rjq|A7w2}o^g9-6`Z`1Z zNO~Z!1(Uu!z_?q~xxKeHos+;>8Agk*I3u(oqX>UXGiKng@0E-hKm~En#eHZ;Z*Qf8 zw!jx2nqka3m=TyWEDLz<=Vv|9+l$vtG_5!zNZ3Z)qx--f0W1$NY}<;9bh~ipI$&qB zI|w@3ZGbk3kalnO%^sfSTQl@~$lEMDjtBxA!rcg(VuTh=LXebzM9g`K>gyNE=Dh~I zc;s*MUQg)~N1xOHf2k8+Y2%jxUJv}kPQ33yK|tB-aQ_ncA}7Al=6@XUKLUS_6Mut^ z-v{`wflqVdXW97UfWHWQffFCI@n--(4*W_d-d86GMguk)WqjGr-d;W-v3%!SVBu!~ zzYO?ST==6Fp6{<@J=xofH(71|kK6j!0Y41*^PTu|8~-@)0pQm-@xHhve;@S&e~}Y^ zi_L!=_*;OV;>0)E_%pzN68N+Ee>65*HUn?A3sJxPhE56e&kW!{`T5@7E1dFcZ28N8 zUkALa?%iqQ*8#sB__NvnIPjkXewK|uSC1AopJdV33zPpka= z6NUY`0G$DT+`snr);syb_xM`^zRH8Mo)a~Ra&rBeRtLIyPC8#$=;0H?65t;K{zW!q zvmMU4*MCo-CC&fc!4!2^RZA@hk~rw|ztY?LNyIJsk`}+O_Mjjm&10bX)Zd`l2bv?G zInh_n8&VE!?*z@3r?I)}r17n{e8dIsN#Ngh;eRFYLBN8*f90#ay?pfIvh@L5M+s=g zeyz8+%t_-bwRBVgzYzGd^%I+bUkdypS2-;Z<-|NZ3H<$E@9llrCI2N${vqH$`b_`* zL@szv0AB$7Z&2ROJotaYKg2OI>)`V98$! zd<=N;^w_Ki{#+{`G2r9)WB}(Xmi(1MywHC?@SA}zclqH)!Owd36!6b}tG9O$%GBaF z>)D@?7e_s#J;y=chTo50hPXu^we{gAsMe8g zq3QQv8S+pp7^UKRsnUYpEYf1mcNA==!2cNep?3-DXc(nHOCut_OcDcqw!AanydVEw z|6@2%A71}OJTPOq*<+w>S0Rq?Ry8_crvNJgtiS6J;Ky-ysf>^;C>x<3in@d2P*wq2JUll2XRlpU4;9ixaZ(5!@UIe3fwW=aop>0 z--G)B+@HbyIow~s{WR`paUa6{67HYi?!^5Y+}*hUirYY*&S740{ZGil54DnLEEM z59#?0Rf$-1Zbf}nEIJDv31MWIB^T0~_H*C7dT6VNVcpwTLB78Vz5&CbYO9;8EVAlj`r<PvdSJgEk^V$NLuI3l#G_4Y;=4d=p(byP?uWbaRRf}-nx+$(btVJrL z@Q9`j)gyHcEAZtDJ<@>9YJk3^lTFIF&R4Ob0rWTcup=hu%Mfd*!<#rhxE*^4Sa{g|7tP0DCrg|Et_9n^#pf#ZAkYxeqVl0qn0mJtg#^GyWHP;QWon+GyORZ6Pgy zHyA&>{&#tR^K>p_%_sa%j|^!&V+G*DKmQ9nu<2Z@{PpW@C=V6~i}I)D7ic;jFsUc! z#aA!G)0gW$zHDXl+U8|=rnIcKVP$mL?M)Sl=4H)ImCNuLXBnQ3$C{V%In*-6sj({U zQp1WbFgQ`qISC%lV8)~Qe1n^7F_#Luq52>(jq!69mZ;W(zPl!1jUR|K#+x)>3*)|V zNLEt9rYl7<5Qwa(z&y*hS)z?Vq&iknqxtTU_;jT4#7XnrE7MtE$5e^peOn|b8zK_b zc!Hz(S|ubW5Q(pBtmb1W&3B&^JX%W&Y(QKe z3rK*>YMRU{6N7a={*Q3(tm!*+y6C&OdFh74l_h}syiV}jxVe#_e-l|9QVB34zHP|8 zZdjfZE*mPDKQ3m8`oHO9U7H;epRm;n(ZYwwC&ilnZ%p~NX+!Gj`Pu~lQw1O}tWMK+ zi~Mhk4HJ*fB6uPw-jvYvFH1x%oG=|Wqy=VzDV_cp-Wb7DIWD}a>CfpTq~_hY`P4?w z&>K+%P0c3B4+RO)-^JZYl7FUwd^JPUe<-cN6CAKbo0>HJRh@K)aOXg@{yoyJY_0*q zB+UdVALU1y8!IXyyMujv!_0ofw?a~h^nccYN z<%{s;kjRQyMg8rX{%0YA?9brtpa?85g^2e|5m`z#CfIn0sp&&>!9<2F=c2bI(?5Y} z1oRFQD3G*))31^QL>8SF z(sl?5*mxWP_5@ru*;4Fai?9}GdPwq;ZxQZeD*U zA-1M3keuXd#hry*>W_jmJ0ZzPA>AZ$f1@RAln^GH$r4>B^S5!&rGW2IHGFk*AL?>G zz%FfA9c?PZlWt94uIuD^J|`qTB(1MV)3kGku(~Zbm7a@l}Ex8fJJb$ ztf5)c@7Hx&+>Lt=bNh8LQQrfmKJ5a*gr&5_^RTXye(L!l@d;`DPvFU}h8YiwrjN#c zt}yapB_p7Xl!}|f>Sd`}tMEjq1{j;*nDC{QOdGNM=HFmtEh|ek!nkH>u6mMvX zT88Y>b@Hsmy_|e^S$w-pzU)Tka+iJ+yyDvy&^{t8Ss2AC8*f!;`g^)g_MsPqw8tny z;>#P+Z$<^daGy@(H6ICSM@gXEQQNRuy#J%=SNe1!zlhs_BlKx_{4^Spi+n7J(P&O8 zCTq8uV2`ZgHK3j>s7KU*Tt)(*7N+BUWhoIKOOIWg|FRTFFw)D*NJw*v-+V22G#q7llKmlX9^Xq~eAUhmf_ zE$xz!wuBOIRT3MOkQgO?QYA#`nu$j3LRGh`5|vR^z-#?FMRnnBqd3_RvF){FDK@?| zeYY*qP1m%G#Bh}96wZ0FzCnto z=vQ!Wq4+A$pPQ{Aw!ySj4hI{Qk%1BD`!=dX?Fd?Om$D?Le0`mI!;qg8Exmg)M6N zhO(xAN1otn2?g{d61{}tM^F@YBg5@1z*$>w^?4GWB@l<#(8bDQs9 zYWg3Pj%6dv6~H^HWR_s?t*OA<-YXkcMI+cm*YseTPNiSPy@QIgNKn@-k$GvN;t@Hj z2=hP^EY6^1jnI>qwiOkGQ`am^-s&)9O_lVdD9)Hr5qQM`e!dENt(a&k&pt5 zS$A0SoMZFN z(Rf3|nnTYQlTA?Y1Ks09yJuyi#7J|zqA4B`*0hQ_7s&YOnjFr*j4W$bD%i}5De3Ri zdt|OUKrisDZV~yKsir?8Dg(sjB6k7}U0g0aYa;SYL{s#WcyAbQ5j(2>UXzNST@mb+ z=3B~|en@m^%ricTVX4N{--Ppv9il*fWM<*8m|l;R)EENkDCyJZ^t~X0Fn$+VFbx`^ z^8LJE`if*ickbdltn;`8^5LT@bypdU5S9jI+K8l%;ZObkB)Vq-9Ly=-Fmkr06~yNOxm zFCX+*Od5Vh#YIzS(Y$KX@bf2vCdLI-Wup1X94A^@e9A=g!!-h3!=LR$M29R^OTRTK z_$lYU6jUOperHncFe{_k17b#H;`seHA;H8&rc9O{6957^yqBN?2UZAA2`JhNwe5}5IfXM_?g-1Bpg=c zB22$TqxRwX3VLb!ypaxt8BRGSMoG$a8tK4ctz~hg+42cTmg6<+A2h8%Q4LQxuK#uuZqUTl}ewdpf}9_s|qJ>zWY*QOKj;q_n7 z1ALd+r$u3yuD_Qt9Dj9G0S&iadG(}~{MFT@6?OHK^7AL*hh~%TTVV;j>dHytK_L;= zfAwQG@#{4EXSdDqs=9`J%xjtZG#{UN`FH60%w{(t@~3~!pPoPSt!;_jOABYV;4X}e7Pz)SJGQM_dSy*wn=$1hJB&%&t{DH?QluZV z6NNx--)=13=Fc+n{msE0+l+!8OE1~o0BYmh!kOC>OABk3?gg2U__;ybpZ7#|FP&Lf z+j4!&O#hJl+HG&$r0jZlX<_Yl#Id7}KZh0cp~6oy`4IoS!$03sh}c8M$hYu?A(^R1 zi4sJ{)e2rGKgi`G35@c*_5@9^A6(p>4Z;`6C+?*XNhkc_9g-bT9BeX5QzUEKKs1XDXI& zsqlDRjZrF!Lz+I>tO$20f|G?c1;$t=c0GD|E~2}4GvUAEDgTf*{~h_46f6~hU4Z%q z{bA6f1>H+``|mg+*n@+!r|3%G7DoxutLb6G060-e@J!hBfbgQJHGmmzrtYQux;}Rm}ui;jdKcXkL`QN zHzWJC*Ix6lmFA)G4>iv5$DcLHGC@|ebm`8>@_qjV~Lk zwj+irD*tXb>WnXM|MfBB*wUrjQ@>ul!#8f^%qwz*Lk2xN$p5uFji;{l|4<9wR_h<~ ztpASSJI1lS=thP#>LzAZu2+cwE~&FbMD@@Z^!f7pWnd-`9$Hv#!`VnRr~U` z9h+d3vEA5?+UARm@?D+nyLuErOkR@B2>xHrzs4lrxSZYoA$QMwX!ozi74Aikn0P+% zRswxq+tLh{{;vkBi8V zCH}RD%v|>IamJUIF7>DTa&lau&+`G34*hME($FO1QU;nu0NWM#c?>exJ-A!+?m#Ek35x6pZ0u z88;ZdCgKT$Az$`kSVD4TgUZ@r1$f9SOJinC@0EhVRO_!EhKV9m|1X zx`^BQm>#ZR3^QfiVAvw!34`G#3Agkyy;;E+-Yeqn#I?ffy#AAr)w40)O>%bj5k*4pG_c)p0+ zd`w@UU<^mgxWTYk#8J->mPk0H$&2Z*f-$^K#tnw|h%oM;qwx1@iF~^f-!ti#tnu`#hNu?FuYmBZND&m zi-Iw{RmKg5_u-*D{mC#X;x-@C_bV8~2V~q}*dyWzgW;bg+_IDDzbF{PGcs;4oP`}U z>SH)t#BF^{7b_UUu#6iFhoeI!AHxh0xA~aPR4|4kWZYo5LBtaV!#gG1vXkkJ3dZnm z88;aIPQ()iLq76yws)p~uV4({k#U3JkMS6db~1cL#BDp7epSI3z9!=a!^IdR$j7i; z#BDyNZ&EOZOJv+&cr|vr$j9&+5x4o6o}pk2KPuw}!yk!w!eGeLS)BP}`o{{!@KqT% z7+#Dw9;lDuSP{4NF+EPf7><{5gW+5ePZ$j6Nw`%GOn*$l7?#So!SG+O^G#cS z3@?>&gCUQ~qhA=7inz_k^n3+lxIo4YhU-K;VK7`T;g+3DZ%{CX8)e*J_#^z7g8CS~ zEaJ94rhlwp3}2OTgW+rV&&BVkXaja0Gx z+bWwFwexOzm32sZ74L4?&kz(Jya}H?ZRY(f{^8o~yC#j`JRgv^U6ApBtVPk-b@fU> zb}NWa!%xZi;}iVq-1IXAg+Rlv>e%)920*%9kmZ0>pondn^?*F%f+PXif@)>cdIY`*fczt{ACw}tI$8YAm;&6in)o+ zl?%v)n045YX@C^CAaek@0IxIJGz$RA>Divr}y6hDQ z{9%8af3#*SOIYS;mV&EUgHH#o{0DT!+w=N za3iT-p9VRTTqI@>xeZX+L&jsx&56doWA%9u@bo3J1kW~7Urr^Lnx!0xMAlSA?hs=J zItqASLMp@#pM=nqnc!-(xU9M%bkXKFK|^Z$GV4YNAbPGpd(65KLXD7h!&5c1{Nja+ zbC;BsaBLFx=*$3|<+v10F)?SQQDf7S@Ggti-=7?~)f7v8elZSGs(mS4H?z!bT{fOE zMKg=>v(i9U?#(yfj75N$8TfT~p2(X|npv}EaWt0p^g|>3Q*tv${j=(lG_&a4v(W&h zu^yIzfH_9{;$PhMW!A%g0!Y?F2(F1WtZ-CBvu^CTRF+b|<*ud)A;^(+!|h{gH0ws0 zRW}HAU#30n09*EmufEs@eGq#}Am?w@Rok9^Y*sVsFIx7**N6|u*yf;2<(&5K@sDj! zKf2VMcJbfgpMSUPsccL{s-qQgd_lL_Hj2OKl=cMi^I{P9xx6+X2Zg)aG~4@JVE&d5 zZJWLMqH5N|V^%$!hLqbVv)m5=W0gC;gp{tXbzX3HB=GA%5DJH`o0^UuJ%LB;ONoCEB#`e*vadl5Rr z^4Q}@xl73O*qgvekKx57&TedH388yoLgy9lQ#Ts(3#U#g6kj(M^;vMe1g4|?Fsg45ADjtB%;>TB@Dd~kc}?LL_j)S<#jzERW6zcAdM5vQl_AdfN1$9#Ot3N zxS;=b@%Q-0(yj-g#(S|$LzsxNR$v~Ezl_BB#xoMf32_i5T}U8c=DL@xf{%XE|J zF`cFFzW&j=wphB{dYJO)vifJs^VVF#lB4Cu&mS3(c78U(t^G-l_D+xXpLnz%9gy~?JlZ#UwD0q1zsIBf z*nqU}@@QY@(Z0u{eVs>p=YX`|@6o>8qn$G&SLsaos7HHhK-!=2Xy-S7T)K)5d9;7V zqy6-Nv~%CsrEBtI9__Dqv_I?7-ZLQWk9)K?dbB^~(Z0f?otsi%$hw3m7Eo;4utogVFcH_M&((;n@A^=Qu-koH$R z+IM-hpYUk!^k@$bNc$0w_QyTik9o8o@@UT+koIF9?R>!4fV4m9(Z0r`{TYvTo_*rhzGOh!`OPd>9h)5UXy4`0zQm(_ z`GBlR2%9*Cy}*O0CG& zrRvXPW-fr~dwJ$;{n4mBMr)s>KN?xbuFN*=(HTRQ9GBWlDY9)gcUK%XtGw5}Pu|VF zo&Usq6`esogrED{t5of)!}R>wX{Mes>xRxJ(eBHWuMae%4w;gzJ*%K;j|nMS28FJ6 zF(u}iQSUHo%Lme)=h1F>w3m3aciS|ouI?I;_5zRgEL*ZHog%JE+<8C8llP|wq`k$b%%h!e&nSCT-uDbhd#OkJ1dsMwkM=Klw08_h`&^IqJdgG&kM_qr+K&uKd#*=& zz@t6n(SF>fQJz0KAnhd{?YXvORqK{}wBP5+`>_FOpWxA+?$JKiqa8ot>{IJH2c&(5 zNBd}x_9Y(ei#^&?1JWM!Xy+D$t92L6@Mu3|)2MPkJs|DVJlbMzB_DIdEfj#c{j(w|HOP1 z#jJdxaQj?lE(*+2exLEZ%&Z$a-|TW<=JU86R^BV^_k{83LG#fje+k8}>Ch56gW3ZK z$1gA{$oBw|{t5Q`-19%vhs-6PMOrrNtO4%I=y|`lA0JZA>sG#yQys5U_L)PHCIygXu>90YI92pj$g zo8<^gNCcnd;#cT`qUD-21_Ugw32D7}-YvN<1!PB-dfojv7Z=}&T&ygVTnlIj zE~X^p6M*0(dQm2jBaf8QJswrfSCQfgz#M?IewWr{XHOyakJG*nlu`M%l6nbK+Kgm z{ERm(W06YH*1@Q__?y2DETC))`SopHww!uGkS`l@FCYZ~+FXwcuAqbFtAMayvAKRA zXyhA!(&k@yAisA(q|JAT_gih7b-ami%ql_FaK1EIYeA6EMu29TtG0{>WRHtx3LtY` z<+T8iLoRPD1Eka?habh=<&v`wkUcJ%Bp~uadFgm9yiXrR+!LTV;?lJTkQZH$?*r0l zLGZR14{Foovp?2^i2Tsqs!l8e?6P=OX}2M70 zO9*~iZcCm=NT$yL`2-;HxiBr{6$2#TqWKgc=E_CVJPe3j6Pa9}2Ly$q+2#ICKn$0h z?*n4)>PtDV0}=$6ZQ%(((p_Bq(6?K%fhF>jmVY9Vs#q)%ffQ%$Jr^`PEE?j*s)ejC{odfOPiMf!m_Y!t^_2@Wpe`{nig`jrVW79x+LF68e~k_ zBaa8vdSAX_Xs5p~4hMprKOfySKEN}G=W;;t=kQ}RX5n(!w;X4sPD zCmBVbVCQs5I{G@8&1Nqpj{+puCFcr2cDU@h8jv!@A-S$2jd(iAoXUQq0u*Nbk&r5( z$F5N~fh)Vf9IZ&ruZ{CkK8)b~;>i5P%i&eq<~V5bTo&E~$Syml>d-~`wAA$cr$Mv$ z=T85$17g0-D|4|MkO?lydja7kZRY!;ILfD5K7ThQe;+gj7MJQ1DvK-#`HzF9)Rl{r zOEPKx0!ZA>17(U3%!z8sbSLvJ!8jhaQW06XEJmnUPCK8bcW0ru1 z`IdRVR83>;@#1Pgrnz!)tD>>FVt_ni*$iRY9e_OLg7Ew4RANj17eLHaq}2W`Kte8E zF95RKCFduAbmlut@NGccW88ayXfCcH8PElwtl{`=m-sUD2}=%-4Xt8tgVM2E!ANkG zxa5ol#N2C=HqQVgWyygGtrU<`79^q$;*@Wyn6;$>G|m~CJSudFRXUW@0Gf4{b}>W4 zk(~uDnhl^iZRsM{!+;!d(fk`Ayll^R0ur+%6Zcy{x-B^odH5*uMK_u@`!hi}$?5s? z2)W7$$s+_#v~|q_1Wt8~Ad3V|$U(Cl5YC}&u6jV8aap(ykVY5eK0uy!K^_C7%7R4X zVXfMlNzPn+0W?L>W%nd|0Ff7RD%QCW(dYUBXacUB{v41smM)TaQL+mnYLkmA9j*w1 z)~bj6z`GW7(VWjZ=#rBUNC>xT%j%%kX_L%+MdTr|TF8RXo;lz+?SfPSV!m}RYi~0k zn_Rm1ors_d!nwS>=pXzjPXoHo^=;4)YM0=vlvC`i8^2L8_(RzMxX@ZO9d_YRz zSyfx)am1S8l3WOyqb^7Y5Eh~BjR+tGF3Amm6uBUG0@7*8iKvr?<@-^nEtmtSBbF^1 z+WaWErn%(&D$M&OohFp?|1Hy`D&o{;Z(&)11 zQgXRw1y=zQaCzfKK-yf82q4oSS^D`?NaaUsvDoIBf%#R@6^R-Q-WByV(PlGQ#}9X# zs1+-kqN~i57>*PMRlx!`@Yw2z_zEj$L5p~pL!uF|n)*Z}Y962+ktb?5g^D!sQv@gF z$Ls3n<981ZkZmPIhv!D-ESxnz9GM-yZr%+T0Rj71@xn;yyhV#;3O}5{2_ZFgIKH7t z^5`9_#L+faUry$nYg%9uQt5CgA$R3H+LQvs23oZyF4pTqh*5a%&`3JK5g zfIXGs!FejmV}n$bhvC^#dB7c<*5}|l0THLqNu2v+xd@LHAa;&Av`qjU2eL_mehycY zgw7+=1jIW1Or-3y&Lp{YvYAMFjvNzEcv_x)BU1C4&9l8!(maPtB>SA1)fdK7uLNvi z)IPUL0IXB0M9Mt&+M5$e%KK@>P?y$W3+Vk1JwjO%3sAC5mzi#V;(sVeve4sb!18 zv;z}H!2{EECm8bWJUb$rP0!OzjsJ+_r zS4S&u&qo)&3Qa}!*~K_`su{oYgz$d5a;X<*PplEu41J?o8H&avPOW04b{r(6Y(;NS zierYttc4*|I5hwAdN~qRh0UP}jTPet2PT<8W%7-QXwzCz^XU(D!h}#LPHT~8#lT{= z8_NeIH9uD>PS+3&{hTeNbS;iG!^WFbi=d^87ittCyK-5xi_wzm zP<K@-QQ=xgtqF2_b&jsRuLHz#{{W!WKa#T3r3$* zRKky_!F6a6tPea#DAG_(?^NC%!D$~W>*7SvNoIM)S&!U={H1FX4*Q~rl@+%&G~sNI z6*$&89$gt(6>Vxpre&j`o3K@FIUk)8A$9#g$gXs2%p-tg)8oo462ZGrjvR}&A~%2qA1bc%02C-bd)qg=8?!uWqnLEK%S{Y8 zLa~tdw**;B5xd)CxKU6uZstSeN974bDg{V@*TuU4ars|8MKjI=p$>TmZ zDxR9a@dPp3SM0W|Mk*=>K9?hQP!zM;^{_>8OhI9z!ZkFzYMSt=`V3SA=S)>pq5fJ8 zRqBMbtjo-{=pQhJLzTd%ipA02qQVL>st;?Htv7zWe-{y_2Rj_1j;2!Ps3(VDXZX%(HxgiO~!5 zLwC_j152Y7tD^n%<22EE?wgV)cJ6Hto5d|V%|3OQ)yH-R2QByT@=sofRt^t`5*S9?6OocX%=~kBxkGMY9;ltbvMymvF7xHBl+G<8R|Cv0tiEYX4i9 zBZf!woWB0%O46NnGnd^BCq`nYU5Uhe%Gpw_GNev1aWUJSFttycca3|^i3W4nd*7)D znx5m!9cI?V<9%h*-5j8p*V>`I&su2PKy za=ht(f+KPLW>}1@R++Err;Ul@?W}5WmOj~Rg|4FJ%1_O3`c6-Uze=J!w9VUQG5otu z4;5|`hN@xs{dza6Yhk9&KD?PT6b!$%o2{9$Ytbs6Cy6DNtm=toE(%#}vjXe*r=nM#caD literal 19968 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 diff --git a/Marlin/utf_mapper.h b/Marlin/utf_mapper.h index ad13e3654..d54be6ceb 100644 --- a/Marlin/utf_mapper.h +++ b/Marlin/utf_mapper.h @@ -9,14 +9,18 @@ #define HARDWAERE_CHAR_OUT lcd.write #endif -#if !(defined( DISPLAY_CHARSET_HD44780_JAPAN ) || defined( DISPLAY_CHARSET_HD44780_WESTERN ) || defined( DISPLAY_CHARSET_HD44780_CYRILIC )) - #define DISPLAY_CHARSET_HD44780_JAPAN -#endif - -#ifndef DOGLCD - #ifdef DISPLAY_CHARSET_KANJI - #error("Kanji does not work on character based displays!"); - #elif defined( DISPLAY_CHARSET_HD44780_JAPAN ) +#ifndef SIMULATE_ROMFONT + #if defined( DISPLAY_CHARSET_ISO10646_1 ) && defined( DOGLCD ) + #define MAPPER_ONE_TO_ONE + #elif defined( DISPLAY_CHARSET_ISO10646_5 ) && defined( DOGLCD ) + #define MAPPER_ONE_TO_ONE + #elif defined( DISPLAY_CHARSET_ISO10646_KANA ) && defined( DOGLCD ) + #define MAPPER_ONE_TO_ONE + #elif defined( DISPLAY_CHARSET_KANJI ) && defined( DOGLCD ) + #define MAPPER_NON + #endif +#else // SIMULATE_ROMFONT + #if defined( DISPLAY_CHARSET_HD44780_JAPAN ) #if defined( MAPPER_C2C3 ) const PROGMEM uint8_t utf_recode[] = { // 0 1 2 3 4 5 6 7 8 9 a b c d e f This is fair for symbols @@ -27,11 +31,11 @@ 0x3f,0x3f,0x3f,0x3f,0xe1,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f, // c38 // ä 0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0xef,0x78,0x3f,0x3f,0x3f,0x3f,0xf5,0x3f,0x3f,0xe2, // c39 missing characters display as '?' - // ö x ü ä + // ö x ü ß 0x3f,0x3f,0x3f,0x3f,0xe1,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f, // c3a // ä - 0x3f,0xee,0x3f,0x3f,0x3f,0x3f,0xef,0xed,0x3f,0x3f,0x3f,0x3f,0xf5,0x3f,0x3f,0x3f // c3b - // n ö ü + 0x3f,0xee,0x3f,0x3f,0x3f,0x3f,0xef,0xfd,0x3f,0x3f,0x3f,0x3f,0xf5,0x3f,0x3f,0x3f // c3b + // n ö ÷ ü }; #elif defined( MAPPER_E382E383 ) const PROGMEM uint8_t utf_recode[] = @@ -115,14 +119,8 @@ #elif defined( MAPPER_E382E383 ) #error( "Katakana on a cyrillic display makes no sense. There are no matching symbols." ); #endif - #endif -#else //DOGLCD - #if defined( DISPLAY_CHARSET_KANJI ) - #define MAPPER_NON - #else - #define MAPPER_ONE_TO_ONE - #endif -#endif //DOGLCD + #endif // DISPLAY_CHARSET_HD44780_CYRILIC +#endif // SIMULATE_ROMFONT #if defined( MAPPER_NON ) char charset_mapper(char c){ @@ -193,20 +191,18 @@ uint8_t utf_hi_char; // UTF-8 high part bool seen_d5 = false; char charset_mapper(char c){ - // it is a Russian alphabet translation - // except 0401 --> 0xa2 = Ё, 0451 --> 0xb5 = ё uint8_t d = c; - if ( d >= 0x80 ) { // UTF-8 handling - if ((d >= 0xd0) && (!seen_d5)) { - utf_hi_char = d - 0xd0; + if ( d >= 0x80u ) { // UTF-8 handling + if ((d >= 0xd0u) && (!seen_d5)) { + utf_hi_char = d - 0xd0u; seen_d5 = true; return 0; } else if (seen_d5) { - d &= 0x3f; + d &= 0x3fu; #ifndef MAPPER_ONE_TO_ONE HARDWAERE_CHAR_OUT( (char) pgm_read_byte_near( utf_recode + d + ( utf_hi_char << 6 ) - 0x20) ); #else - HARDWAERE_CHAR_OUT( (char) (0x80 + ( utf_hi_char << 6 ) + d) ) ; + HARDWAERE_CHAR_OUT( (char) (0xa0u + ( utf_hi_char << 6 ) + d) ) ; #endif } else { HARDWAERE_CHAR_OUT('?');