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
+ },
}