diff --git a/Marlin/dogm_lcd_implementation.h b/Marlin/dogm_lcd_implementation.h
index 4e2a567fff6613a265c83a9dd013ba32955054d4..171b42733ac0b267f810f6afba7ebf2fb2a123e9 100644
--- a/Marlin/dogm_lcd_implementation.h
+++ b/Marlin/dogm_lcd_implementation.h
@@ -17,8 +17,8 @@
 #define MARLIN_VERSION "1.0.2"
 
 /**
-* Implementation of the LCD display routines for a DOGM128 graphic display. These are common LCD 128x64 pixel graphic displays.
-**/
+ * Implementation of the LCD display routines for a DOGM128 graphic display. These are common LCD 128x64 pixel graphic displays.
+ */
 
 #ifdef ULTIPANEL
   #define BLEN_A 0
@@ -32,35 +32,72 @@
 
 #include <U8glib.h>
 #include "DOGMbitmaps.h"
-#include "dogm_font_data_marlin.h"
 #include "ultralcd.h"
 #include "ultralcd_st7920_u8glib_rrd.h"
+#include "configuration.h"
+#include "utf_mapper.h"
 
-/* Russian language not supported yet, needs custom font
+#include <utility/u8g.h>
+#include "dogm_font_data_6x9_marlin.h"       // Height of 'A' is only 5 pixel.
+#include "dogm_font_data_Marlin_symbols.h"   // The Marlin special symbols
 
-#ifdef LANGUAGE_RU
-#include "LiquidCrystalRus.h"
-#define LCD_CLASS LiquidCrystalRus
-#else
-#include <LiquidCrystal.h>
-#define LCD_CLASS LiquidCrystal
+#define FONT_STATUSMENU_NAME u8g_font_6x9    // we don't have a small font for Cyrillic, Kana or Kanji
+#define FONT_SPECIAL_NAME Marlin_symbols
+
+// save 3120 bytes of PROGMEM by commenting out the next #define
+// we don't have a big font for Cyrillic, Kana or Kanji
+#if defined( MAPPER_C2C3 ) || defined( MAPPER_NON )
+  #define USE_BIG_EDIT_FONT
 #endif
-*/
 
-#define USE_BIG_EDIT_FONT                // save 3120 bytes of PROGMEM by commenting out this line
-#define FONT_STATUSMENU u8g_font_6x9
-#define FONT_MENU u8g_font_6x10_marlin
+#if defined( MAPPER_C2C3 )
+  #include <utility/u8g.h> // 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 <utility/u8g.h> // system font
+  #define FONT_MENU_NAME u8g_font_6x10
+#endif
+
+#define FONT_STATUSMENU 1
+#define FONT_SPECIAL 2
+#define FONT_MENU_EDIT 3
+#define FONT_MENU 4
 
 // DOGM parameters (size in pixels)
 #define DOG_CHAR_WIDTH         6
 #define DOG_CHAR_HEIGHT        12
 #ifdef USE_BIG_EDIT_FONT
-  #define FONT_MENU_EDIT u8g_font_9x18
+  #define FONT_MENU_EDIT_NAME u8g_font_9x18
   #define DOG_CHAR_WIDTH_EDIT  9
   #define DOG_CHAR_HEIGHT_EDIT 18
   #define LCD_WIDTH_EDIT       14
 #else
-  #define FONT_MENU_EDIT u8g_font_6x10_marlin
+  #define FONT_MENU_EDIT_NAME FONT_MENU_NAME
   #define DOG_CHAR_WIDTH_EDIT  6
   #define DOG_CHAR_HEIGHT_EDIT 12
   #define LCD_WIDTH_EDIT       22
@@ -68,16 +105,21 @@
 
 #define START_ROW              0
 
-/* Custom characters defined in font font_6x10_marlin.c */
-#define LCD_STR_DEGREE      "\xB0"
-#define LCD_STR_REFRESH     "\xF8"
-#define LCD_STR_FOLDER      "\xF9"
-#define LCD_STR_ARROW_RIGHT "\xFA"
-#define LCD_STR_UPLEVEL     "\xFB"
-#define LCD_STR_CLOCK       "\xFC"
-#define LCD_STR_FEEDRATE    "\xFD"
-#define LCD_STR_BEDTEMP     "\xFE"
-#define LCD_STR_THERMOMETER "\xFF"
+/* Custom characters defined in font font_6x10_marlin_symbols */
+// \x00 intentionally skipped to avoid problems in strings
+#define LCD_STR_REFRESH     "\x01"
+#define LCD_STR_FOLDER      "\x02"
+#define LCD_STR_ARROW_RIGHT "\x03"
+#define LCD_STR_UPLEVEL     "\x04"
+#define LCD_STR_CLOCK       "\x05"
+#define LCD_STR_FEEDRATE    "\x06"
+#define LCD_STR_BEDTEMP     "\x07"
+#define LCD_STR_THERMOMETER "\x08"
+#define LCD_STR_DEGREE      "\x09"
+
+#define LCD_STR_SPECIAL_MAX LCD_STR_DEGREE
+// Maximum here is 0x1f because 0x20 is ' ' (space) and the normal charsets begin.
+// Better stay below 0x10 because DISPLAY_CHARSET_HD44780_WESTERN begins here.
 
 int lcd_contrast;
 
@@ -96,6 +138,49 @@ U8GLIB_NHD_C12864 u8g(DOGLCD_CS, DOGLCD_A0);
 U8GLIB_DOGM128 u8g(DOGLCD_CS, DOGLCD_A0);  // HW-SPI Com: CS, A0
 #endif
 
+char currentfont = 0;
+
+static void lcd_setFont(char font_nr) {
+  switch(font_nr) {
+    case FONT_STATUSMENU : {u8g.setFont(FONT_STATUSMENU_NAME); currentfont = FONT_STATUSMENU;}; break;
+    case FONT_MENU       : {u8g.setFont(FONT_MENU_NAME); currentfont = FONT_MENU;}; break;
+    case FONT_SPECIAL    : {u8g.setFont(FONT_SPECIAL_NAME); currentfont = FONT_SPECIAL;}; break;
+    case FONT_MENU_EDIT  : {u8g.setFont(FONT_MENU_EDIT_NAME); currentfont = FONT_MENU_EDIT;}; break;
+    break;
+  }
+}
+
+char lcd_print(char c) {
+  if ((c > 0) && (c < ' ')) {
+    u8g.setFont(FONT_SPECIAL_NAME);
+    u8g.print(c);
+    lcd_setFont(currentfont);
+    return 1;
+  } else {
+    return charset_mapper(c);
+  }
+}
+
+char lcd_print(char* str) {
+  char c;
+  int i = 0;
+  char n = 0;
+  while ((c = str[i++])) {
+    n += lcd_print(c);
+  }
+  return n;
+}
+
+/* Arduino < 1.0.0 is missing a function to print PROGMEM strings, so we need to implement our own */
+char lcd_printPGM(const char* str) {
+  char c;
+  char n = 0;
+  while ((c = pgm_read_byte(str++))) {
+    n += lcd_print(c);
+  }
+  return n;
+}
+
 static void lcd_implementation_init()
 {
   #ifdef LCD_PIN_BL // Enable LCD backlight
@@ -130,7 +215,7 @@ static void lcd_implementation_init()
 	u8g.firstPage();
 	do {
     u8g.drawBitmapP(offx, offy, START_BMPBYTEWIDTH, START_BMPHEIGHT, start_bmp);
-    u8g.setFont(FONT_MENU);
+    lcd_setFont(FONT_MENU);
     #ifndef STRING_SPLASH_LINE2
       u8g.drawStr(txt1X, u8g.getHeight() - DOG_CHAR_HEIGHT, STRING_SPLASH_LINE1);
     #else
@@ -143,21 +228,15 @@ static void lcd_implementation_init()
 
 static void lcd_implementation_clear() { } // Automatically cleared by Picture Loop
 
-/* Arduino < 1.0.0 is missing a function to print PROGMEM strings, so we need to implement our own */
-static void lcd_printPGM(const char* str) {
-  char c;
-  while ((c = pgm_read_byte(str++))) u8g.print(c);
-}
-
 static void _draw_heater_status(int x, int heater) {
   bool isBed = heater < 0;
   int y = 17 + (isBed ? 1 : 0);
-  u8g.setFont(FONT_STATUSMENU);
+  lcd_setFont(FONT_STATUSMENU);
   u8g.setPrintPos(x,6);
-  u8g.print(itostr3(int((heater >= 0 ? degTargetHotend(heater) : degTargetBed()) + 0.5)));
+  lcd_print(itostr3(int((heater >= 0 ? degTargetHotend(heater) : degTargetBed()) + 0.5)));
   lcd_printPGM(PSTR(LCD_STR_DEGREE " "));
   u8g.setPrintPos(x,27);
-  u8g.print(itostr3(int(heater >= 0 ? degHotend(heater) : degBed()) + 0.5));
+  lcd_print(itostr3(int(heater >= 0 ? degHotend(heater) : degBed()) + 0.5));
   lcd_printPGM(PSTR(LCD_STR_DEGREE " "));
   if (!isHeatingHotend(0)) {
     u8g.drawBox(x+7,y,2,2);
@@ -189,7 +268,7 @@ static void lcd_implementation_status_screen() {
     u8g.drawFrame(54,49,73,4);
 
     // SD Card Progress bar and clock
-    u8g.setFont(FONT_STATUSMENU);
+    lcd_setFont(FONT_STATUSMENU);
  
     if (IS_SD_PRINTING) {
       // Progress bar solid part
@@ -199,9 +278,9 @@ static void lcd_implementation_status_screen() {
     u8g.setPrintPos(80,47);
     if (starttime != 0) {
       uint16_t time = (millis() - starttime) / 60000;
-      u8g.print(itostr2(time/60));
-      u8g.print(':');
-      u8g.print(itostr2(time%60));
+      lcd_print(itostr2(time/60));
+      lcd_print(':');
+      lcd_print(itostr2(time%60));
     }
     else {
       lcd_printPGM(PSTR("--:--"));
@@ -215,68 +294,77 @@ static void lcd_implementation_status_screen() {
   if (EXTRUDERS < 4) _draw_heater_status(81, -1);
  
   // Fan
-  u8g.setFont(FONT_STATUSMENU);
+  lcd_setFont(FONT_STATUSMENU);
   u8g.setPrintPos(104,27);
   #if defined(FAN_PIN) && FAN_PIN > -1
     int per = ((fanSpeed + 1) * 100) / 256;
     if (per) {
-      u8g.print(itostr3(per));
-      u8g.print("%");
+      lcd_print(itostr3(per));
+      lcd_print('%');
     }
     else
   #endif
     {
-      u8g.print("---");
+      lcd_printPGM(PSTR("---"));
     }
 
   // X, Y, Z-Coordinates
-  u8g.setFont(FONT_STATUSMENU);
+  lcd_setFont(FONT_STATUSMENU);
   u8g.drawBox(0,29,128,10);
   u8g.setColorIndex(0); // white on black
   u8g.setPrintPos(2,37);
-  u8g.print("X");
+  lcd_print('X');
   u8g.drawPixel(8,33);
   u8g.drawPixel(8,35);
   u8g.setPrintPos(10,37);
-  u8g.print(ftostr31ns(current_position[X_AXIS]));
+  lcd_print(ftostr31ns(current_position[X_AXIS]));
   u8g.setPrintPos(43,37);
-  lcd_printPGM(PSTR("Y"));
+  lcd_print('Y');
   u8g.drawPixel(49,33);
   u8g.drawPixel(49,35);
   u8g.setPrintPos(51,37);
-  u8g.print(ftostr31ns(current_position[Y_AXIS]));
+  lcd_print(ftostr31ns(current_position[Y_AXIS]));
   u8g.setPrintPos(83,37);
-  u8g.print("Z");
+  lcd_print('Z');
   u8g.drawPixel(89,33);
   u8g.drawPixel(89,35);
   u8g.setPrintPos(91,37);
-  u8g.print(ftostr31(current_position[Z_AXIS]));
+  lcd_print(ftostr31(current_position[Z_AXIS]));
   u8g.setColorIndex(1); // black on white
  
   // Feedrate
-  u8g.setFont(FONT_MENU);
+  lcd_setFont(FONT_MENU);
   u8g.setPrintPos(3,49);
-  u8g.print(LCD_STR_FEEDRATE[0]);
-  u8g.setFont(FONT_STATUSMENU);
+  lcd_print(LCD_STR_FEEDRATE[0]);
+  lcd_setFont(FONT_STATUSMENU);
   u8g.setPrintPos(12,48);
-  u8g.print(itostr3(feedmultiply));
-  u8g.print('%');
+  lcd_print(itostr3(feedmultiply));
+  lcd_print('%');
 
   // Status line
-  u8g.setFont(FONT_STATUSMENU);
+/* The new fonts are small enough
+  #ifndef MAPPER_C2C3
+    lcd_setFont(FONT_MENU);
+  #else
+    lcd_setFont(FONT_STATUSMENU);
+  #endif
+*/
+  lcd_setFont(FONT_MENU);
+
   u8g.setPrintPos(0,61);
+
   #ifndef FILAMENT_LCD_DISPLAY
-    u8g.print(lcd_status_message);
+    lcd_print(lcd_status_message);
   #else
     if (millis() < message_millis + 5000) {  //Display both Status message line and Filament display on the last line
-      u8g.print(lcd_status_message);
+      lcd_print(lcd_status_message);
     }
     else {
       lcd_printPGM(PSTR("dia:"));
-      u8g.print(ftostr12ns(filament_width_meas));
+      lcd_print(ftostr12ns(filament_width_meas));
       lcd_printPGM(PSTR(" factor:"));
-      u8g.print(itostr3(extrudemultiply));
-      u8g.print('%');
+      lcd_print(itostr3(extrudemultiply));
+      lcd_print('%');
     }
   #endif
 }
@@ -300,13 +388,12 @@ static void lcd_implementation_drawmenu_generic(uint8_t row, const char* pstr, c
   lcd_implementation_mark_as_selected(row, pre_char);
 
   while((c = pgm_read_byte(pstr))) {
-    u8g.print(c);
+    n -= lcd_print(c);
     pstr++;
-    n--;
   }
-  while(n--) u8g.print(' ');
-  u8g.print(post_char);
-  u8g.print(' ');
+  while(n--) lcd_print(' ');
+  lcd_print(post_char);
+  lcd_print(' ');
 }
 
 static void _drawmenu_setting_edit_generic(uint8_t row, const char* pstr, char pre_char, const char* data, bool pgm) {
@@ -316,13 +403,12 @@ static void _drawmenu_setting_edit_generic(uint8_t row, const char* pstr, char p
   lcd_implementation_mark_as_selected(row, pre_char);
 
   while( (c = pgm_read_byte(pstr))) {
-    u8g.print(c);
+    n -= lcd_print(c);
     pstr++;
-    n--;
   }
-  u8g.print(':');
-  while(n--) u8g.print(' ');
-  if (pgm) { lcd_printPGM(data); } else { u8g.print(data); }
+  lcd_print(':');
+  while(n--) lcd_print(' ');
+  if (pgm) { lcd_printPGM(data); } else { lcd_print((char *)data); }
 }
 
 #define lcd_implementation_drawmenu_setting_edit_generic(row, pstr, pre_char, data) _drawmenu_setting_edit_generic(row, pstr, pre_char, data, false)
@@ -374,13 +460,13 @@ void lcd_implementation_drawedit(const char* pstr, char* value) {
 
   #ifdef USE_BIG_EDIT_FONT
     if (lcd_strlen_P(pstr) <= LCD_WIDTH_EDIT - 1) {
-      u8g.setFont(FONT_MENU_EDIT);
+      lcd_setFont(FONT_MENU_EDIT);
       lcd_width = LCD_WIDTH_EDIT + 1;
       char_width = DOG_CHAR_WIDTH_EDIT;
       if (lcd_strlen_P(pstr) >= LCD_WIDTH_EDIT - lcd_strlen(value)) rows = 2;
     }
     else {
-      u8g.setFont(FONT_MENU);
+      lcd_setFont(FONT_MENU);
     }
   #endif
 
@@ -391,9 +477,9 @@ void lcd_implementation_drawedit(const char* pstr, char* value) {
 
   u8g.setPrintPos(0, rowHeight + kHalfChar);
   lcd_printPGM(pstr);
-  u8g.print(':');
+  lcd_print(':');
   u8g.setPrintPos((lcd_width-1-lcd_strlen(value)) * char_width, rows * rowHeight + kHalfChar);
-  u8g.print(value);
+  lcd_print(value);
 }
 
 static void _drawmenu_sd(uint8_t row, const char* pstr, const char* filename, char * const longFilename, bool isDir, bool isSelected) {
@@ -407,13 +493,12 @@ static void _drawmenu_sd(uint8_t row, const char* pstr, const char* filename, ch
 
   lcd_implementation_mark_as_selected(row, ((isSelected) ? '>' : ' '));
 
-  if (isDir) u8g.print(LCD_STR_FOLDER[0]);
+  if (isDir) lcd_print(LCD_STR_FOLDER[0]);
   while((c = *filename) != '\0') {
-    u8g.print(c);
+    n -= lcd_print(c);
     filename++;
-    n--;
   }
-  while(n--) u8g.print(' ');
+  while(n--) lcd_print(' ');
 }
 
 #define lcd_implementation_drawmenu_sdfile_selected(row, pstr, filename, longFilename) _drawmenu_sd(row, pstr, filename, longFilename, false, true)