font/sfnt: don't reject multiple kern subtables.

A future commit will actually use subtables past the first one, but for
now, ignore them instead of failing on their presence.

Also add tests for the DejaVu proprietary fonts. Prior to this commit,
DejaVuSans-ExtraLight.ttf was unsupported.

Change-Id: Ic78a59c5ab30e4091efa2a04b89b12cb786157db
Reviewed-on: https://go-review.googlesource.com/42192
Reviewed-by: David Crawshaw <crawshaw@golang.org>
This commit is contained in:
Nigel Tao 2017-04-30 17:13:35 +10:00
parent d442804300
commit f483456c9f
2 changed files with 73 additions and 4 deletions

View File

@ -19,7 +19,11 @@ End User License Agreement (EULA) and a CAB format decoder. These tests assume
that such fonts have already been installed. You may need to specify the
directories for these fonts:
go test golang.org/x/image/font/sfnt -args -proprietary -adobeDir=$HOME/fonts/adobe -appleDir=$HOME/fonts/apple -microsoftDir=$HOME/fonts/microsoft
go test golang.org/x/image/font/sfnt -args -proprietary \
-adobeDir=$HOME/fonts/adobe \
-appleDir=$HOME/fonts/apple \
-dejavuDir=$HOME/fonts/dejavu \
-microsoftDir=$HOME/fonts/microsoft
To only run those tests for the Microsoft fonts:
@ -72,6 +76,13 @@ var (
"directory name for the Apple proprietary fonts",
)
dejavuDir = flag.String(
"dejavuDir",
// Get the fonts from https://dejavu-fonts.github.io/
"",
"directory name for the DejaVu proprietary fonts",
)
microsoftDir = flag.String(
"microsoftDir",
"/usr/share/fonts/truetype/msttcorefonts",
@ -143,6 +154,18 @@ func TestProprietaryAppleHiragino1(t *testing.T) {
testProprietary(t, "apple", "ヒラギノ角ゴシック W0.ttc?1", 9000, -1)
}
func TestProprietaryDejaVuSansExtraLight(t *testing.T) {
testProprietary(t, "dejavu", "DejaVuSans-ExtraLight.ttf", 2000, -1)
}
func TestProprietaryDejaVuSansMono(t *testing.T) {
testProprietary(t, "dejavu", "DejaVuSansMono.ttf", 3300, -1)
}
func TestProprietaryDejaVuSerif(t *testing.T) {
testProprietary(t, "dejavu", "DejaVuSerif.ttf", 3500, -1)
}
func TestProprietaryMicrosoftArial(t *testing.T) {
testProprietary(t, "microsoft", "Arial.ttf", 1200, -1)
}
@ -192,6 +215,8 @@ func testProprietary(t *testing.T, proprietor, filename string, minNumGlyphs, fi
dir = *adobeDir
case "apple":
dir = *appleDir
case "dejavu":
dir = *dejavuDir
case "microsoft":
dir = *microsoftDir
default:
@ -375,6 +400,10 @@ var proprietaryVersions = map[string]string{
"apple/ヒラギノ角ゴシック W0.ttc?0": "11.0d7e1",
"apple/ヒラギノ角ゴシック W0.ttc?1": "11.0d7e1",
"dejavu/DejaVuSans-ExtraLight.ttf": "Version 2.37",
"dejavu/DejaVuSansMono.ttf": "Version 2.37",
"dejavu/DejaVuSerif.ttf": "Version 2.37",
"microsoft/Arial.ttf": "Version 2.82",
"microsoft/Arial.ttf?0": "Version 2.82",
"microsoft/Comic_Sans_MS.ttf": "Version 2.10",
@ -403,6 +432,10 @@ var proprietaryFullNames = map[string]string{
"apple/ヒラギノ角ゴシック W0.ttc?0": "Hiragino Sans W0",
"apple/ヒラギノ角ゴシック W0.ttc?1": ".Hiragino Kaku Gothic Interface W0",
"dejavu/DejaVuSans-ExtraLight.ttf": "DejaVu Sans ExtraLight",
"dejavu/DejaVuSansMono.ttf": "DejaVu Sans Mono",
"dejavu/DejaVuSerif.ttf": "DejaVu Serif",
"microsoft/Arial.ttf": "Arial",
"microsoft/Arial.ttf?0": "Arial",
"microsoft/Comic_Sans_MS.ttf": "Comic Sans MS",
@ -469,6 +502,11 @@ var proprietaryGlyphIndexTestCases = map[string]map[rune]GlyphIndex{
'\U0001f100': 0, // U+0001F100 DIGIT ZERO FULL STOP
},
"dejavu/DejaVuSerif.ttf": {
'\u0041': 36, // U+0041 LATIN CAPITAL LETTER A
'\u1e00': 1418, // U+1E00 LATIN CAPITAL LETTER A WITH RING BELOW
},
"microsoft/Arial.ttf": {
'\u0041': 36, // U+0041 LATIN CAPITAL LETTER A
'\u00f1': 120, // U+00F1 LATIN SMALL LETTER N WITH TILDE
@ -930,6 +968,23 @@ var proprietaryGlyphTestCases = map[string]map[rune][]Segment{
},
},
"dejavu/DejaVuSans-ExtraLight.ttf": {
'i': {
// - contour #0
moveTo(230, 1120),
lineTo(322, 1120),
lineTo(322, 0),
lineTo(230, 0),
lineTo(230, 1120),
// - contour #1
moveTo(230, 1556),
lineTo(322, 1556),
lineTo(322, 1430),
lineTo(230, 1430),
lineTo(230, 1556),
},
},
"microsoft/Arial.ttf": {
',': {
// - contour #0
@ -1109,6 +1164,18 @@ type kernTestCase struct {
// proprietaryKernTestCases hold a sample of each font's kerning pairs. The
// numerical values can be verified by running the ttx tool.
var proprietaryKernTestCases = map[string][]kernTestCase{
"dejavu/DejaVuSans-ExtraLight.ttf": {
{2048, font.HintingNone, [2]rune{'A', 'A'}, 57},
{2048, font.HintingNone, [2]rune{'W', 'A'}, -112},
// U+00C1 LATIN CAPITAL LETTER A WITH ACUTE
// U+01FA LATIN CAPITAL LETTER A WITH RING ABOVE AND ACUTE
// U+1E82 LATIN CAPITAL LETTER W WITH ACUTE
{2048, font.HintingNone, [2]rune{'\u00c1', 'A'}, 57},
// TODO: enable these next two test cases, when we support multiple
// kern subtables.
// {2048, font.HintingNone, [2]rune{'\u01fa', 'A'}, 57},
// {2048, font.HintingNone, [2]rune{'\u1e82', 'A'}, -112},
},
"microsoft/Arial.ttf": {
{2048, font.HintingNone, [2]rune{'A', 'V'}, -152},
// U+03B8 GREEK SMALL LETTER THETA

View File

@ -869,9 +869,11 @@ func (f *Font) parseKern(buf []byte) (buf1 []byte, kernNumPairs, kernOffset int3
switch version := u16(buf); version {
case 0:
// TODO: support numTables != 1. Testing that requires finding such a font.
if numTables := int(u16(buf[2:])); numTables != 1 {
return nil, 0, 0, errUnsupportedKernTable
if numTables := int(u16(buf[2:])); numTables == 0 {
return buf, 0, 0, nil
} else if numTables > 1 {
// TODO: support multiple subtables. For now, fall through and use
// only the first one.
}
return f.parseKernVersion0(buf, offset, length)
case 1: