font/sfnt: support Symbol fonts such as MS Webdings.

Change-Id: I1297246dad6288345b4b87b885fbeda06a6516ff
Reviewed-on: https://go-review.googlesource.com/37031
Reviewed-by: David Crawshaw <crawshaw@golang.org>
diff --git a/font/sfnt/cmap.go b/font/sfnt/cmap.go
index e6e114e..cc5aa51 100644
--- a/font/sfnt/cmap.go
+++ b/font/sfnt/cmap.go
@@ -25,8 +25,9 @@
 
 	psidMacintoshRoman = 0
 
-	psidWindowsUCS2 = 1
-	psidWindowsUCS4 = 10
+	psidWindowsSymbol = 0
+	psidWindowsUCS2   = 1
+	psidWindowsUCS4   = 10
 )
 
 // platformEncodingWidth returns the number of bytes per character assumed by
@@ -61,6 +62,8 @@
 
 	case pidWindows:
 		switch psid {
+		case psidWindowsSymbol:
+			return 2
 		case psidWindowsUCS2:
 			return 2
 		case psidWindowsUCS4:
diff --git a/font/sfnt/proprietary_test.go b/font/sfnt/proprietary_test.go
index dc0d725..71911e3 100644
--- a/font/sfnt/proprietary_test.go
+++ b/font/sfnt/proprietary_test.go
@@ -63,27 +63,20 @@
 	)
 )
 
-type proprietor int
-
-const (
-	adobe proprietor = iota
-	microsoft
-)
-
 func TestProprietaryAdobeSourceCodeProOTF(t *testing.T) {
-	testProprietary(t, adobe, "SourceCodePro-Regular.otf", 1500, 2)
+	testProprietary(t, "adobe", "SourceCodePro-Regular.otf", 1500, 2)
 }
 
 func TestProprietaryAdobeSourceCodeProTTF(t *testing.T) {
-	testProprietary(t, adobe, "SourceCodePro-Regular.ttf", 1500, 36)
+	testProprietary(t, "adobe", "SourceCodePro-Regular.ttf", 1500, 36)
 }
 
 func TestProprietaryAdobeSourceHanSansSC(t *testing.T) {
-	testProprietary(t, adobe, "SourceHanSansSC-Regular.otf", 65535, 2)
+	testProprietary(t, "adobe", "SourceHanSansSC-Regular.otf", 65535, 2)
 }
 
 func TestProprietaryAdobeSourceSansProOTF(t *testing.T) {
-	testProprietary(t, adobe, "SourceSansPro-Regular.otf", 1800, 2)
+	testProprietary(t, "adobe", "SourceSansPro-Regular.otf", 1800, 2)
 }
 
 func TestProprietaryAdobeSourceSansProTTF(t *testing.T) {
@@ -91,23 +84,23 @@
 	// version of the file has fewer glyphs than the (presumably canonical) OTF
 	// version. The number of glyphs in the .otf and .ttf files can be verified
 	// with the ttx tool.
-	testProprietary(t, adobe, "SourceSansPro-Regular.ttf", 1000, 56)
+	testProprietary(t, "adobe", "SourceSansPro-Regular.ttf", 1000, 56)
 }
 
 func TestProprietaryMicrosoftArial(t *testing.T) {
-	testProprietary(t, microsoft, "Arial.ttf", 1200, 98)
+	testProprietary(t, "microsoft", "Arial.ttf", 1200, 98)
 }
 
 func TestProprietaryMicrosoftComicSansMS(t *testing.T) {
-	testProprietary(t, microsoft, "Comic_Sans_MS.ttf", 550, 98)
+	testProprietary(t, "microsoft", "Comic_Sans_MS.ttf", 550, 98)
 }
 
 func TestProprietaryMicrosoftTimesNewRoman(t *testing.T) {
-	testProprietary(t, microsoft, "Times_New_Roman.ttf", 1200, 98)
+	testProprietary(t, "microsoft", "Times_New_Roman.ttf", 1200, 98)
 }
 
 func TestProprietaryMicrosoftWebdings(t *testing.T) {
-	testProprietary(t, microsoft, "Webdings.ttf", 200, -1)
+	testProprietary(t, "microsoft", "Webdings.ttf", 200, -1)
 }
 
 // testProprietary tests that we can load every glyph in the named font.
@@ -119,23 +112,25 @@
 // firstUnsupportedGlyph argument, if non-negative, is the index of the first
 // unsupported glyph in the font. This number should increase over time (or set
 // negative), as the TODO's in this package are done.
-func testProprietary(t *testing.T, p proprietor, filename string, minNumGlyphs, firstUnsupportedGlyph int) {
+func testProprietary(t *testing.T, proprietor, filename string, minNumGlyphs, firstUnsupportedGlyph int) {
 	if !*proprietary {
 		t.Skip("skipping proprietary font test")
 	}
 
 	file, err := []byte(nil), error(nil)
-	switch p {
-	case adobe:
+	switch proprietor {
+	case "adobe":
 		file, err = ioutil.ReadFile(filepath.Join(*adobeDir, filename))
 		if err != nil {
 			t.Fatalf("%v\nPerhaps you need to set the -adobeDir=%v flag?", err, *adobeDir)
 		}
-	case microsoft:
+	case "microsoft":
 		file, err = ioutil.ReadFile(filepath.Join(*microsoftDir, filename))
 		if err != nil {
 			t.Fatalf("%v\nPerhaps you need to set the -microsoftDir=%v flag?", err, *microsoftDir)
 		}
+	default:
+		panic("unreachable")
 	}
 	f, err := Parse(file)
 	if err != nil {
@@ -161,4 +156,94 @@
 			t.Fatal("LoadGlyph: too many errors")
 		}
 	}
+
+	for r, want := range proprietaryGlyphIndexTestCases[proprietor+"/"+filename] {
+		got, err := f.GlyphIndex(&buf, r)
+		if err != nil {
+			t.Errorf("GlyphIndex(%q): %v", r, err)
+			continue
+		}
+		if got != want {
+			t.Errorf("GlyphIndex(%q): got %d, want %d", r, got, want)
+			continue
+		}
+	}
+}
+
+// proprietaryGlyphIndexTestCases hold a sample of each font's rune to glyph
+// index cmap. The numerical values can be verified by running the ttx tool.
+var proprietaryGlyphIndexTestCases = map[string]map[rune]GlyphIndex{
+	"adobe/SourceCodePro-Regular.otf": {
+		'\u0030':     877,  // U+0030 DIGIT ZERO
+		'\u0041':     2,    // U+0041 LATIN CAPITAL LETTER A
+		'\u0061':     28,   // U+0061 LATIN SMALL LETTER A
+		'\u0104':     64,   // U+0104 LATIN CAPITAL LETTER A WITH OGONEK
+		'\u0125':     323,  // U+0125 LATIN SMALL LETTER H WITH CIRCUMFLEX
+		'\u01f4':     111,  // U+01F4 LATIN CAPITAL LETTER G WITH ACUTE
+		'\u03a3':     623,  // U+03A3 GREEK CAPITAL LETTER SIGMA
+		'\u2569':     1500, // U+2569 BOX DRAWINGS DOUBLE UP AND HORIZONTAL
+		'\U0001f100': 0,    // U+0001F100 DIGIT ZERO FULL STOP
+	},
+	"adobe/SourceCodePro-Regular.ttf": {
+		'\u0030': 877, // U+0030 DIGIT ZERO
+		'\u0041': 2,   // U+0041 LATIN CAPITAL LETTER A
+		'\u01f4': 111, // U+01F4 LATIN CAPITAL LETTER G WITH ACUTE
+	},
+	"adobe/SourceHanSansSC-Regular.otf": {
+		'\u0030':     17,    // U+0030 DIGIT ZERO
+		'\u0041':     34,    // U+0041 LATIN CAPITAL LETTER A
+		'\u00d7':     150,   // U+00D7 MULTIPLICATION SIGN
+		'\u1100':     365,   // U+1100 HANGUL CHOSEONG KIYEOK
+		'\u25ca':     1254,  // U+25CA LOZENGE
+		'\u2e9c':     1359,  // U+2E9C CJK RADICAL SUN
+		'\u304b':     1463,  // U+304B HIRAGANA LETTER KA
+		'\u4e2d':     9893,  // U+4E2D <CJK Ideograph>, δΈ­
+		'\ua960':     47537, // U+A960 HANGUL CHOSEONG TIKEUT-MIEUM
+		'\ufb00':     58919, // U+FB00 LATIN SMALL LIGATURE FF
+		'\uffee':     59213, // U+FFEE HALFWIDTH WHITE CIRCLE
+		'\U0001f100': 59214, // U+0001F100 DIGIT ZERO FULL STOP
+		'\U0001f248': 59449, // U+0001F248 TORTOISE SHELL BRACKETED CJK UNIFIED IDEOGRAPH-6557
+		'\U0002f9f4': 61768, // U+0002F9F4 CJK COMPATIBILITY IDEOGRAPH-2F9F4
+	},
+	"adobe/SourceSansPro-Regular.otf": {
+		'\u0041': 2,    // U+0041 LATIN CAPITAL LETTER A
+		'\u03a3': 592,  // U+03A3 GREEK CAPITAL LETTER SIGMA
+		'\u0435': 999,  // U+0435 CYRILLIC SMALL LETTER IE
+		'\u2030': 1728, // U+2030 PER MILLE SIGN
+	},
+	"adobe/SourceSansPro-Regular.ttf": {
+		'\u0041': 4,   // U+0041 LATIN CAPITAL LETTER A
+		'\u03a3': 0,   // U+03A3 GREEK CAPITAL LETTER SIGMA
+		'\u0435': 0,   // U+0435 CYRILLIC SMALL LETTER IE
+		'\u2030': 675, // U+2030 PER MILLE SIGN
+	},
+
+	"microsoft/Arial.ttf": {
+		'\u0041':     36,   // U+0041 LATIN CAPITAL LETTER A
+		'\u00f1':     120,  // U+00F1 LATIN SMALL LETTER N WITH TILDE
+		'\u0401':     556,  // U+0401 CYRILLIC CAPITAL LETTER IO
+		'\u200d':     745,  // U+200D ZERO WIDTH JOINER
+		'\u20ab':     1150, // U+20AB DONG SIGN
+		'\u2229':     320,  // U+2229 INTERSECTION
+		'\u04e9':     1319, // U+04E9 CYRILLIC SMALL LETTER BARRED O
+		'\U0001f100': 0,    // U+0001F100 DIGIT ZERO FULL STOP
+	},
+	"microsoft/Comic_Sans_MS.ttf": {
+		'\u0041': 36,  // U+0041 LATIN CAPITAL LETTER A
+		'\u03af': 573, // U+03AF GREEK SMALL LETTER IOTA WITH TONOS
+	},
+	"microsoft/Times_New_Roman.ttf": {
+		'\u0041': 36,  // U+0041 LATIN CAPITAL LETTER A
+		'\u0042': 37,  // U+0041 LATIN CAPITAL LETTER B
+		'\u266a': 392, // U+266A EIGHTH NOTE
+		'\uf041': 0,   // PRIVATE USE AREA
+		'\uf042': 0,   // PRIVATE USE AREA
+	},
+	"microsoft/Webdings.ttf": {
+		'\u0041': 0,  // U+0041 LATIN CAPITAL LETTER A
+		'\u0042': 0,  // U+0041 LATIN CAPITAL LETTER B
+		'\u266a': 0,  // U+266A EIGHTH NOTE
+		'\uf041': 36, // PRIVATE USE AREA
+		'\uf042': 37, // PRIVATE USE AREA
+	},
 }