Index: doc/options.txt
===================================================================
--- doc/options.txt	(revision 4823)
+++ doc/options.txt	(working copy)
@@ -145,11 +145,10 @@
 === Label options ===
 
 ;--code-page=number
-:     Specify which international character set is to be used. Only 8 bit
-character sets are supported so you have to specify which code page you
-want to use.
-It is entirely dependent on the device firmware which code pages are
-supported.
+:     Specify which character set is to be used.
+The default is --code-page=0 which uses a 6-bit encoding of ASCII characters.
+Mkgmap supports many 8-bit code-pages and Unicode. Other, multi-byte, code-pages might work.
+It is entirely dependent on the device firmware which code pages they support.
 
 ;--latin1
 : 	This is equivalent to --code-page=1252.
@@ -159,8 +158,10 @@
 Unicode maps produced by mkgmap.
 
 ;--lower-case
-: 	Allow labels to contain lower case letters.  Note that many
-Garmin devices are not able to display lower case letters at an angle.
+: 	Allow labels to contain lower case letters.
+Note that some older Garmin devices are not able to display lower case letters at an angle.
+Also note that newer devices InitCap text, so, even without this option, text appears as mixed case.
+This option is ignored when using the default code-page=0.
 
 === Address search options ===
 
Index: resources/help/en/options
===================================================================
--- resources/help/en/options	(revision 4823)
+++ resources/help/en/options	(working copy)
@@ -145,10 +145,10 @@
 === Label options ===
 
 --code-page=number
-    Specify which international character set is to be used. Only 8 bit
-    character sets are supported so you have to specify which code page you
-    want to use. It is entirely dependent on the device firmware which code
-    pages are supported.
+    Specify which character set is to be used. The default is --code-page=0
+    which uses a 6-bit encoding of ASCII characters. Mkgmap supports many 8-bit
+    code-pages and Unicode. Other, multi-byte, code-pages might work. It is
+    entirely dependent on the device firmware which code pages they support.
 
 --latin1
     This is equivalent to --code-page=1252.
@@ -158,8 +158,10 @@
     support Unicode maps produced by mkgmap.
 
 --lower-case
-    Allow labels to contain lower case letters. Note that many Garmin devices
-    are not able to display lower case letters at an angle.
+    Allow labels to contain lower case letters. Note that some older Garmin
+    devices are not able to display lower case letters at an angle. Also note
+    that newer devices InitCap text, so, even without this option, text appears
+    as mixed case. This option is ignored when using the default code-page=0.
 
 === Address search options ===
 
Index: src/uk/me/parabola/imgfmt/app/labelenc/BaseEncoder.java
===================================================================
--- src/uk/me/parabola/imgfmt/app/labelenc/BaseEncoder.java	(revision 4823)
+++ src/uk/me/parabola/imgfmt/app/labelenc/BaseEncoder.java	(working copy)
@@ -28,7 +28,7 @@
  * @author Steve Ratcliffe
  */
 public class BaseEncoder {
-	private static final Logger log = Logger.getLogger(BaseEncoder.class);
+	protected static final Logger log = Logger.getLogger(BaseEncoder.class);
 
 	public static final EncodedText NO_TEXT = new EncodedText(null, 0, null);
 
Index: src/uk/me/parabola/imgfmt/app/labelenc/Format6Decoder.java
===================================================================
--- src/uk/me/parabola/imgfmt/app/labelenc/Format6Decoder.java	(revision 4823)
+++ src/uk/me/parabola/imgfmt/app/labelenc/Format6Decoder.java	(working copy)
@@ -83,22 +83,10 @@
 		if (symbol) {
 			symbol = false;
 			c = Format6Encoder.SYMBOLS.charAt(b);
-		}
-		else if(lowerCaseOrSeparator) {
+		} else if (lowerCaseOrSeparator) {
 			lowerCaseOrSeparator = false;
-			if(b == 0x2b || b == 0x2c) {
-				c = (char)(b - 0x10); // "thin" separator
-			}
-			else if(Character.isLetter(b)) {
-				// lower case letter
-				c = Character.toLowerCase(Format6Encoder.LETTERS.charAt(b));
-			}
-			else {
-				// not a letter so just use as is (could be a digit)
-				c = Format6Encoder.LETTERS.charAt(b);
-			}
-		}
-		else {
+			c = Format6Encoder.LOWERCASE.charAt(b);
+		} else {
 			switch(b) {
 			case 0x1B:
 				// next char is lower case or a separator
@@ -110,13 +98,6 @@
 				symbol = true;
 				return;
 
-			case 0x1D:
-			case 0x1E:
-			case 0x1F:
-				// these are separators - use as is
-				c = (char)b;
-				break;
-
 			default:
 				c = Format6Encoder.LETTERS.charAt(b);
 				break;
Index: src/uk/me/parabola/imgfmt/app/labelenc/Format6Encoder.java
===================================================================
--- src/uk/me/parabola/imgfmt/app/labelenc/Format6Encoder.java	(revision 4823)
+++ src/uk/me/parabola/imgfmt/app/labelenc/Format6Encoder.java	(working copy)
@@ -17,12 +17,11 @@
 package uk.me.parabola.imgfmt.app.labelenc;
 
 import java.text.Normalizer;
-import java.util.Locale;
 
 /**
- * Format according to the '6 bit' .img format.  The text is first upper
- * cased.  Any letter with a diacritic or accent is replaced with its base
- * letter.
+ * Format according to the '6 bit' .img format.
+ * Any letter with a diacritic or accent is replaced with its base letter.
+ * Characters from other alphabets are transliterated if resources/chars/ascii/ data exists.
  *
  * For example Körnerstraße would become KORNERSTRASSE,
  * Řípovská would become RIPOVSKA etc.
@@ -32,25 +31,44 @@
  *
  * @author Steve Ratcliffe
  * @see <a href="http://garmin-img.sf.net">Garmin IMG File Format</a>
+ *
+ * Although Format6 supports lower-case, the default is to forceUpper and ignore request
+ * to change to mixed-case.
+ * The main reason for this is that indexed searching for streets has been found not to
+ * work in some cases.
+ * Another reason is that each lower-case letter needs 12 bits, so, with typical OSM data,
+ * almost any other code-page will be more compact.
  */
 public class Format6Encoder extends BaseEncoder implements CharacterEncoder {
 
-	// This is 0x1b is the source document, but the accompanying code uses
-	// the value 0x1c, which seems to work.
-	private static final int SYMBOL_SHIFT = 0x1c;
+	// Following are swapped in the above John Mechalas document, but this is what works:
+	private static final int LOWERCASE_SHIFT = 0x1b;
+	private static final int SYMBOL_SHIFT    = 0x1c;
 
 	public static final String LETTERS =
 		" ABCDEFGHIJKLMNO" +	// 0x00-0x0F
-		"PQRSTUVWXYZxx   " +	// 0x10-0x1F
-		"0123456789\u0001\u0002\u0003\u0004\u0005\u0006";	// 0x20-0x2F
+		"PQRSTUVWXYZxx\u001d\u001e\u001f" +	// 0x10-0x1F  xx are above SHIFTs. prefix/suffix indicators
+		"0123456789\u0001\u0002\u0003\u0004\u0005\u0006";	// 0x20-0x2F  digits + shields
 
 	public static final String SYMBOLS =
 		"@!\"#$%&'()*+,-./" +	// 0x00-0x0F
-		"xxxxxxxxxx:;<=>?" +	// 0x10-0x1F
-		"xxxxxxxxxxx[\\]^_";	// 0x20-0x2F
+		"          :;<=>?" +	// 0x10-0x1F
+		"°          [\\]^_";	// 0x20-0x2F
+	//   ^ looks like degree (\u00b0) on MapSource/eTrex. Won't happen as transliterated to "deg"
+	//   0123456789abcdef
+	public static final String LOWERCASE =
+		"`abcdefghijklmno" +	// 0x00-0x0F  back-tick
+		"pqrstuvwxyz{|}~ " +	// 0x10-0x1F
+		"           \u001b\u001c   ";     // 0x20-0x2F  more prefix/suffix indicators
 
-	private final Transliterator transliterator = new TableTransliterator("ascii");
+	private final Transliterator transliterator;
 
+	public Format6Encoder() {
+		transliterator = new TableTransliterator("ascii");
+		transliterator.forceUppercase(true);  // default to upper case
+		super.setUpperCase(true);
+	}
+
 	/**
 	 * Encode the text into the 6 bit format.  See the class level notes.
 	 *
@@ -62,7 +80,7 @@
 		if (text == null || text.isEmpty())
 			return NO_TEXT;
 		String normalisedText = Normalizer.normalize(text, Normalizer.Form.NFC);
-		String s = transliterator.transliterate(normalisedText).toUpperCase(Locale.ENGLISH);
+		String s = transliterator.transliterate(normalisedText);  // it does the upper if forceUpper
 
 		// Allocate more than enough space on average for the label.
 		// if you overdo it then it will waste a lot of space , but
@@ -78,8 +96,8 @@
 				put6(buf, off++, c - 'A' + 1);
 			} else if (c >= '0' && c <= '9') {
 				put6(buf, off++, c - '0' + 0x20);
-			} else if (c == 0x1b || c == 0x1c) {
-				put6(buf, off++, 0x1b);
+			} else if (c == 0x1b || c == 0x1c) {  // shiftedLowerCase() does same thing
+				put6(buf, off++, LOWERCASE_SHIFT);
 				put6(buf, off++, c + 0x10);
 			} else if (c >= 0x1d && c <= 0x1f) {
 				put6(buf, off++, c);
@@ -86,8 +104,14 @@
 			} else if (c >= 1 && c <= 6) {
 				// Highway shields
 				put6(buf, off++, 0x29 + c);
+			} else if (c >= 'a' && c <= 'z') {
+				put6(buf, off++, LOWERCASE_SHIFT);
+				put6(buf, off++, c - 'a' + 1);
 			} else {
+				int rememberOff = off;
 				off = shiftedSymbol(buf, off, c);
+				if (off == rememberOff)
+					off = shiftedLowerCase(buf, off, c);
 			}
 		}
 
@@ -119,6 +143,16 @@
 		return off;
 	}
 
+	private int shiftedLowerCase(byte[] buf, int startOffset, char c) {
+		int off = startOffset;
+		int ind = LOWERCASE.indexOf(c);
+		if (ind >= 0) {
+			put6(buf, off++, LOWERCASE_SHIFT);
+			put6(buf, off++, ind);
+		}
+		return off;
+	}
+
 	/**
 	 * Each character is packed into 6 bits.  This keeps track of everything so
 	 * that the character can be put into the right place in the byte array.
@@ -149,4 +183,11 @@
 
 		return buf;
 	}
+
+	@Override
+	public void setUpperCase(boolean upperCase) {
+		// Ignore requests to allow mixed case
+		//super.setUpperCase(upperCase);
+		//transliterator.forceUppercase(upperCase);
+	}
 }
Index: test/uk/me/parabola/imgfmt/app/labelenc/CodeFunctionsTest.java
===================================================================
--- test/uk/me/parabola/imgfmt/app/labelenc/CodeFunctionsTest.java	(revision 4823)
+++ test/uk/me/parabola/imgfmt/app/labelenc/CodeFunctionsTest.java	(working copy)
@@ -28,6 +28,7 @@
 		assertEquals("code page", 0, functions.getCodepage());
 		assertEquals("encoding type", 6, functions.getEncodingType());
 		CharacterEncoder enc = functions.getEncoder();
+		((BaseEncoder) enc).setUpperCase(true);
 
 		EncodedText etext = enc.encodeText("hello world");
 		byte[] ctext = etext.getCtext();
@@ -58,8 +59,13 @@
 		CodeFunctions functions = CodeFunctions.createEncoderForLBL(6, 0);
 
 		CharacterEncoder encoder = functions.getEncoder();
+		((BaseEncoder) encoder).setUpperCase(true);
+
 		// Twülpstedt contains u + "COMBINING DIAERESIS" (0x75 + 0x308)
-		EncodedText text = encoder.encodeText("Körnerstraße, Twülpstedt, Velkomezeříčská, Skólavörðustigur");
+		String tstStr = "Körnerstraße, Twülpstedt, Velkomezeříčská, Skólavörðustigur";
+		//              "12345678901234567890123456789012345678901234567890123456789"
+		assertEquals("tstStr length", 60, tstStr.length()); // check COMBINING DIAERESIS not already combined
+		EncodedText text = encoder.encodeText(tstStr);
 
 		CharacterDecoder decoder = functions.getDecoder();
 		byte[] ctext = text.getCtext();
@@ -70,6 +76,7 @@
 		}
 		String result = decoder.getText().getText();
 		assertEquals("transliterated text", "KORNERSTRASSE, TWULPSTEDT, VELKOMEZERICSKA, SKOLAVORDUSTIGUR", result);
+		assertEquals("result length", 60, result.length()); // ß changed to ss, COMBINING DIAERESIS combined by normalisation
 	}
 
 	/**
@@ -81,8 +88,11 @@
 		CodeFunctions functions = CodeFunctions.createEncoderForLBL("latin1");
 
 		CharacterEncoder encoder = functions.getEncoder();
+		((BaseEncoder) encoder).setUpperCase(false);
 		// Twülpstedt contains u + "COMBINING DIAERESIS" (0x75 + 0x308)
-		EncodedText text = encoder.encodeText("Körnerstraße, Twülpstedt, Velkomezeříčská, Skólavörðustigur");
+		String tstStr = "Körnerstraße, Twülpstedt, Velkomezeříčská, Skólavörðustigur";
+		assertEquals("tstStr length", 60, tstStr.length()); // check COMBINING DIAERESIS not already combined
+		EncodedText text = encoder.encodeText(tstStr);
 
 		CharacterDecoder decoder = functions.getDecoder();
 		byte[] ctext = text.getCtext();
@@ -95,6 +105,7 @@
 		String result = decoder.getText().getText();
 		// Twülpstedt now contains LATIN SMALL LETTER U WITH DIAERESIS (u+00fc)
 		assertEquals("transliterated text", "Körnerstraße, Twülpstedt, Velkomezerícská, Skólavörðustigur", result);
+		assertEquals("result length", 59, result.length()); // COMBINING DIAERESIS combined by normalisation
 	}
 
 	/**
@@ -112,6 +123,7 @@
 		}
 
 		CharacterEncoder encoder = functions.getEncoder();
+		((BaseEncoder) encoder).setUpperCase(false);
 		EncodedText text = encoder.encodeText(sb.toString());
 
 		// This encoder appends a null byte.
