aboutsummaryrefslogtreecommitdiff
path: root/vendor/golang.org/x/image/font
diff options
context:
space:
mode:
authorDimitri Sokolyuk <demon@dim13.org>2018-01-01 22:45:26 +0100
committerDimitri Sokolyuk <demon@dim13.org>2018-01-01 22:45:26 +0100
commit16df0bea5fe8ce0a4ea871d409f589b298567a97 (patch)
treef2f18a2c6773d86a895d075bf8f1a374d48406c4 /vendor/golang.org/x/image/font
parent500caaeda74dd9c660279036293f4b2997cf0b03 (diff)
Update vendor
Diffstat (limited to 'vendor/golang.org/x/image/font')
-rw-r--r--vendor/golang.org/x/image/font/opentype/face.go103
-rw-r--r--vendor/golang.org/x/image/font/opentype/face_test.go90
-rw-r--r--vendor/golang.org/x/image/font/opentype/opentype.go7
-rw-r--r--vendor/golang.org/x/image/font/sfnt/sfnt.go47
-rw-r--r--vendor/golang.org/x/image/font/sfnt/sfnt_test.go34
5 files changed, 275 insertions, 6 deletions
diff --git a/vendor/golang.org/x/image/font/opentype/face.go b/vendor/golang.org/x/image/font/opentype/face.go
new file mode 100644
index 0000000..88c28da
--- /dev/null
+++ b/vendor/golang.org/x/image/font/opentype/face.go
@@ -0,0 +1,103 @@
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package opentype
+
+import (
+ "image"
+
+ "golang.org/x/image/font"
+ "golang.org/x/image/font/sfnt"
+ "golang.org/x/image/math/fixed"
+)
+
+// FaceOptions describes the possible options given to NewFace when
+// creating a new font.Face from a sfnt.Font.
+type FaceOptions struct {
+ Size float64 // Size is the font size in points
+ DPI float64 // DPI is the dots per inch resolution
+ Hinting font.Hinting // Hinting selects how to quantize a vector font's glyph nodes
+}
+
+func defaultFaceOptions() *FaceOptions {
+ return &FaceOptions{
+ Size: 12,
+ DPI: 72,
+ Hinting: font.HintingNone,
+ }
+}
+
+// Face implements the font.Face interface for sfnt.Font values.
+type Face struct {
+ f *sfnt.Font
+ hinting font.Hinting
+ scale fixed.Int26_6
+
+ buf sfnt.Buffer
+}
+
+// NewFace returns a new font.Face for the given sfnt.Font.
+// if opts is nil, sensible defaults will be used.
+func NewFace(f *sfnt.Font, opts *FaceOptions) (font.Face, error) {
+ if opts == nil {
+ opts = defaultFaceOptions()
+ }
+ face := &Face{
+ f: f,
+ hinting: opts.Hinting,
+ scale: fixed.Int26_6(0.5 + (opts.Size * opts.DPI * 64 / 72)),
+ }
+ return face, nil
+}
+
+// Close satisfies the font.Face interface.
+func (f *Face) Close() error {
+ return nil
+}
+
+// Metrics satisfies the font.Face interface.
+func (f *Face) Metrics() font.Metrics {
+ m, err := f.f.Metrics(&f.buf, f.scale, f.hinting)
+ if err != nil {
+ return font.Metrics{}
+ }
+ return m
+}
+
+// Kern satisfies the font.Face interface.
+func (f *Face) Kern(r0, r1 rune) fixed.Int26_6 {
+ x0 := f.index(r0)
+ x1 := f.index(r1)
+ k, err := f.f.Kern(&f.buf, x0, x1, fixed.Int26_6(f.f.UnitsPerEm()), f.hinting)
+ if err != nil {
+ return 0
+ }
+ return k
+}
+
+// Glyph satisfies the font.Face interface.
+func (f *Face) Glyph(dot fixed.Point26_6, r rune) (dr image.Rectangle, mask image.Image, maskp image.Point, advance fixed.Int26_6, ok bool) {
+ panic("not implemented")
+}
+
+// GlyphBounds satisfies the font.Face interface.
+func (f *Face) GlyphBounds(r rune) (bounds fixed.Rectangle26_6, advance fixed.Int26_6, ok bool) {
+ advance, ok = f.GlyphAdvance(r)
+ if !ok {
+ return bounds, advance, ok
+ }
+ panic("not implemented")
+}
+
+// GlyphAdvance satisfies the font.Face interface.
+func (f *Face) GlyphAdvance(r rune) (advance fixed.Int26_6, ok bool) {
+ idx := f.index(r)
+ advance, err := f.f.GlyphAdvance(&f.buf, idx, f.scale, f.hinting)
+ return advance, err == nil
+}
+
+func (f *Face) index(r rune) sfnt.GlyphIndex {
+ x, _ := f.f.GlyphIndex(&f.buf, r)
+ return x
+}
diff --git a/vendor/golang.org/x/image/font/opentype/face_test.go b/vendor/golang.org/x/image/font/opentype/face_test.go
new file mode 100644
index 0000000..224b0f2
--- /dev/null
+++ b/vendor/golang.org/x/image/font/opentype/face_test.go
@@ -0,0 +1,90 @@
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package opentype
+
+import (
+ "testing"
+
+ "golang.org/x/image/font"
+ "golang.org/x/image/font/gofont/goregular"
+ "golang.org/x/image/font/sfnt"
+ "golang.org/x/image/math/fixed"
+)
+
+var (
+ regular font.Face
+)
+
+func init() {
+ font, err := sfnt.Parse(goregular.TTF)
+ if err != nil {
+ panic(err)
+ }
+
+ regular, err = NewFace(font, defaultFaceOptions())
+ if err != nil {
+ panic(err)
+ }
+}
+
+func TestFaceGlyphAdvance(t *testing.T) {
+ for _, test := range []struct {
+ r rune
+ want fixed.Int26_6
+ }{
+ {' ', 213},
+ {'A', 512},
+ {'Á', 512},
+ {'Æ', 768},
+ {'i', 189},
+ {'x', 384},
+ } {
+ got, ok := regular.GlyphAdvance(test.r)
+ if !ok {
+ t.Errorf("could not get glyph advance width for %q", test.r)
+ continue
+ }
+
+ if got != test.want {
+ t.Errorf("%q: glyph advance width=%d. want=%d", test.r, got, test.want)
+ continue
+ }
+ }
+}
+
+func TestFaceKern(t *testing.T) {
+ // FIXME(sbinet) there is no kerning with gofont/goregular
+ for _, test := range []struct {
+ r1, r2 rune
+ want fixed.Int26_6
+ }{
+ {'A', 'A', 0},
+ {'A', 'V', 0},
+ {'V', 'A', 0},
+ {'A', 'v', 0},
+ {'W', 'a', 0},
+ {'W', 'i', 0},
+ {'Y', 'i', 0},
+ {'f', '(', 0},
+ {'f', 'f', 0},
+ {'f', 'i', 0},
+ {'T', 'a', 0},
+ {'T', 'e', 0},
+ } {
+ got := regular.Kern(test.r1, test.r2)
+ if got != test.want {
+ t.Errorf("(%q, %q): glyph kerning=%d. want=%d", test.r1, test.r2, got, test.want)
+ continue
+ }
+ }
+}
+
+func TestFaceMetrics(t *testing.T) {
+ want := font.Metrics{Height: 768, Ascent: 726, Descent: 162}
+ got := regular.Metrics()
+ if got != want {
+ t.Fatalf("metrics failed. got=%#v. want=%#v", got, want)
+ }
+}
diff --git a/vendor/golang.org/x/image/font/opentype/opentype.go b/vendor/golang.org/x/image/font/opentype/opentype.go
new file mode 100644
index 0000000..452e952
--- /dev/null
+++ b/vendor/golang.org/x/image/font/opentype/opentype.go
@@ -0,0 +1,7 @@
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Package opentype implements the font.Face interface based on SFNT
+// font file formats.
+package opentype // import "golang.org/x/image/font/opentype"
diff --git a/vendor/golang.org/x/image/font/sfnt/sfnt.go b/vendor/golang.org/x/image/font/sfnt/sfnt.go
index 53ac94b..cc4ceac 100644
--- a/vendor/golang.org/x/image/font/sfnt/sfnt.go
+++ b/vendor/golang.org/x/image/font/sfnt/sfnt.go
@@ -564,14 +564,17 @@ type Font struct {
kern table
cached struct {
+ ascent int32
glyphData glyphData
glyphIndex glyphIndexFunc
bounds [4]int16
+ descent int32
indexToLocFormat bool // false means short, true means long.
isColorBitmap bool
isPostScript bool
kernNumPairs int32
kernOffset int32
+ lineGap int32
numHMetrics int32
postTableVersion uint32
unitsPerEm Units
@@ -621,7 +624,7 @@ func (f *Font) initialize(offset int, isDfont bool) error {
if err != nil {
return err
}
- buf, numHMetrics, err := f.parseHhea(buf, numGlyphs)
+ buf, ascent, descent, lineGap, numHMetrics, err := f.parseHhea(buf, numGlyphs)
if err != nil {
return err
}
@@ -634,14 +637,17 @@ func (f *Font) initialize(offset int, isDfont bool) error {
return err
}
+ f.cached.ascent = ascent
f.cached.glyphData = glyphData
f.cached.glyphIndex = glyphIndex
f.cached.bounds = bounds
+ f.cached.descent = descent
f.cached.indexToLocFormat = indexToLocFormat
f.cached.isColorBitmap = isColorBitmap
f.cached.isPostScript = isPostScript
f.cached.kernNumPairs = kernNumPairs
f.cached.kernOffset = kernOffset
+ f.cached.lineGap = lineGap
f.cached.numHMetrics = numHMetrics
f.cached.postTableVersion = postTableVersion
f.cached.unitsPerEm = unitsPerEm
@@ -838,20 +844,32 @@ func (f *Font) parseHead(buf []byte) (buf1 []byte, bounds [4]int16, indexToLocFo
return buf, bounds, indexToLocFormat, unitsPerEm, nil
}
-func (f *Font) parseHhea(buf []byte, numGlyphs int32) (buf1 []byte, numHMetrics int32, err error) {
+func (f *Font) parseHhea(buf []byte, numGlyphs int32) (buf1 []byte, ascent, descent, lineGap, numHMetrics int32, err error) {
// https://www.microsoft.com/typography/OTSPEC/hhea.htm
if f.hhea.length != 36 {
- return nil, 0, errInvalidHheaTable
+ return nil, 0, 0, 0, 0, errInvalidHheaTable
}
u, err := f.src.u16(buf, f.hhea, 34)
if err != nil {
- return nil, 0, err
+ return nil, 0, 0, 0, 0, err
}
if int32(u) > numGlyphs || u == 0 {
- return nil, 0, errInvalidHheaTable
+ return nil, 0, 0, 0, 0, errInvalidHheaTable
}
- return buf, int32(u), nil
+ a, err := f.src.u16(buf, f.hhea, 4)
+ if err != nil {
+ return nil, 0, 0, 0, 0, err
+ }
+ d, err := f.src.u16(buf, f.hhea, 6)
+ if err != nil {
+ return nil, 0, 0, 0, 0, err
+ }
+ l, err := f.src.u16(buf, f.hhea, 8)
+ if err != nil {
+ return nil, 0, 0, 0, 0, err
+ }
+ return buf, int32(int16(a)), int32(int16(d)), int32(int16(l)), int32(u), nil
}
func (f *Font) parseHmtx(buf []byte, numGlyphs, numHMetrics int32) (buf1 []byte, err error) {
@@ -1336,6 +1354,23 @@ func (f *Font) Kern(b *Buffer, x0, x1 GlyphIndex, ppem fixed.Int26_6, h font.Hin
return 0, nil
}
+// Metrics returns the metrics of this font.
+func (f *Font) Metrics(b *Buffer, ppem fixed.Int26_6, h font.Hinting) (font.Metrics, error) {
+ m := font.Metrics{
+ // TODO: is adding lineGap correct?
+ Height: ppem + scale(fixed.Int26_6(f.cached.lineGap)*ppem, f.cached.unitsPerEm),
+ Ascent: +scale(fixed.Int26_6(f.cached.ascent)*ppem, f.cached.unitsPerEm),
+ Descent: -scale(fixed.Int26_6(f.cached.descent)*ppem, f.cached.unitsPerEm),
+ }
+ if h == font.HintingFull {
+ // Quantize up to a whole pixel.
+ m.Height = (m.Height + 63) &^ 63
+ m.Ascent = (m.Ascent + 63) &^ 63
+ m.Descent = (m.Descent + 63) &^ 63
+ }
+ return m, nil
+}
+
// Name returns the name value keyed by the given NameID.
//
// It returns ErrNotFound if there is no value for that key.
diff --git a/vendor/golang.org/x/image/font/sfnt/sfnt_test.go b/vendor/golang.org/x/image/font/sfnt/sfnt_test.go
index 74de278..b9b66a7 100644
--- a/vendor/golang.org/x/image/font/sfnt/sfnt_test.go
+++ b/vendor/golang.org/x/image/font/sfnt/sfnt_test.go
@@ -214,6 +214,40 @@ func TestBounds(t *testing.T) {
}
}
+func TestMetrics(t *testing.T) {
+ cmapFont, err := ioutil.ReadFile(filepath.FromSlash("../testdata/cmapTest.ttf"))
+ if err != nil {
+ t.Fatal(err)
+ }
+ testCases := map[string]struct {
+ font []byte
+ want font.Metrics
+ }{
+ "goregular": {goregular.TTF, font.Metrics{Height: 2048, Ascent: 1935, Descent: 432}},
+ // cmapTest.ttf has a non-zero lineGap.
+ "cmapTest": {cmapFont, font.Metrics{Height: 2232, Ascent: 1365, Descent: 0}},
+ }
+ var b Buffer
+ for name, tc := range testCases {
+ f, err := Parse(tc.font)
+ if err != nil {
+ t.Errorf("name=%q: Parse: %v", name, err)
+ continue
+ }
+ ppem := fixed.Int26_6(f.UnitsPerEm())
+
+ got, err := f.Metrics(&b, ppem, font.HintingNone)
+ if err != nil {
+ t.Errorf("name=%q: Metrics: %v", name, err)
+ continue
+ }
+ if got != tc.want {
+ t.Errorf("name=%q: Metrics: got %v, want %v", name, got, tc.want)
+ continue
+ }
+ }
+}
+
func TestGlyphAdvance(t *testing.T) {
testCases := map[string][]struct {
r rune