summaryrefslogtreecommitdiffstats
path: root/Godeps/_workspace/src/github.com/golang/freetype/truetype
diff options
context:
space:
mode:
Diffstat (limited to 'Godeps/_workspace/src/github.com/golang/freetype/truetype')
-rw-r--r--Godeps/_workspace/src/github.com/golang/freetype/truetype/face_test.go48
-rw-r--r--Godeps/_workspace/src/github.com/golang/freetype/truetype/hint_test.go675
-rw-r--r--Godeps/_workspace/src/github.com/golang/freetype/truetype/truetype_test.go400
3 files changed, 0 insertions, 1123 deletions
diff --git a/Godeps/_workspace/src/github.com/golang/freetype/truetype/face_test.go b/Godeps/_workspace/src/github.com/golang/freetype/truetype/face_test.go
deleted file mode 100644
index 856581dff..000000000
--- a/Godeps/_workspace/src/github.com/golang/freetype/truetype/face_test.go
+++ /dev/null
@@ -1,48 +0,0 @@
-// Copyright 2015 The Freetype-Go Authors. All rights reserved.
-// Use of this source code is governed by your choice of either the
-// FreeType License or the GNU General Public License version 2 (or
-// any later version), both of which can be found in the LICENSE file.
-
-package truetype
-
-import (
- "image"
- "image/draw"
- "io/ioutil"
- "strings"
- "testing"
-
- "golang.org/x/image/font"
- "golang.org/x/image/math/fixed"
-)
-
-func BenchmarkDrawString(b *testing.B) {
- data, err := ioutil.ReadFile("../licenses/gpl.txt")
- if err != nil {
- b.Fatal(err)
- }
- lines := strings.Split(string(data), "\n")
- data, err = ioutil.ReadFile("../testdata/luxisr.ttf")
- if err != nil {
- b.Fatal(err)
- }
- f, err := Parse(data)
- if err != nil {
- b.Fatal(err)
- }
- dst := image.NewRGBA(image.Rect(0, 0, 800, 600))
- draw.Draw(dst, dst.Bounds(), image.White, image.ZP, draw.Src)
- d := &font.Drawer{
- Dst: dst,
- Src: image.Black,
- Face: NewFace(f, nil),
- }
- b.ReportAllocs()
- b.ResetTimer()
- for i := 0; i < b.N; i++ {
- for j, line := range lines {
- d.Dot = fixed.P(0, (j*16)%600)
- d.DrawString(line)
- }
- }
-}
diff --git a/Godeps/_workspace/src/github.com/golang/freetype/truetype/hint_test.go b/Godeps/_workspace/src/github.com/golang/freetype/truetype/hint_test.go
deleted file mode 100644
index 7eb43dde0..000000000
--- a/Godeps/_workspace/src/github.com/golang/freetype/truetype/hint_test.go
+++ /dev/null
@@ -1,675 +0,0 @@
-// Copyright 2012 The Freetype-Go Authors. All rights reserved.
-// Use of this source code is governed by your choice of either the
-// FreeType License or the GNU General Public License version 2 (or
-// any later version), both of which can be found in the LICENSE file.
-
-package truetype
-
-import (
- "reflect"
- "strings"
- "testing"
-
- "golang.org/x/image/math/fixed"
-)
-
-func TestBytecode(t *testing.T) {
- testCases := []struct {
- desc string
- prog []byte
- want []int32
- errStr string
- }{
- {
- "underflow",
- []byte{
- opDUP,
- },
- nil,
- "underflow",
- },
- {
- "infinite loop",
- []byte{
- opPUSHW000, // [-1]
- 0xff,
- 0xff,
- opDUP, // [-1, -1]
- opJMPR, // [-1]
- },
- nil,
- "too many steps",
- },
- {
- "unbalanced if/else",
- []byte{
- opPUSHB000, // [0]
- 0,
- opIF,
- },
- nil,
- "unbalanced",
- },
- {
- "vector set/gets",
- []byte{
- opSVTCA1, // []
- opGPV, // [0x4000, 0]
- opSVTCA0, // [0x4000, 0]
- opGFV, // [0x4000, 0, 0, 0x4000]
- opNEG, // [0x4000, 0, 0, -0x4000]
- opSPVFS, // [0x4000, 0]
- opSFVTPV, // [0x4000, 0]
- opPUSHB000, // [0x4000, 0, 1]
- 1,
- opGFV, // [0x4000, 0, 1, 0, -0x4000]
- opPUSHB000, // [0x4000, 0, 1, 0, -0x4000, 2]
- 2,
- },
- []int32{0x4000, 0, 1, 0, -0x4000, 2},
- "",
- },
- {
- "jumps",
- []byte{
- opPUSHB001, // [10, 2]
- 10,
- 2,
- opJMPR, // [10]
- opDUP, // not executed
- opDUP, // [10, 10]
- opPUSHB010, // [10, 10, 20, 2, 1]
- 20,
- 2,
- 1,
- opJROT, // [10, 10, 20]
- opDUP, // not executed
- opDUP, // [10, 10, 20, 20]
- opPUSHB010, // [10, 10, 20, 20, 30, 2, 1]
- 30,
- 2,
- 1,
- opJROF, // [10, 10, 20, 20, 30]
- opDUP, // [10, 10, 20, 20, 30, 30]
- opDUP, // [10, 10, 20, 20, 30, 30, 30]
- },
- []int32{10, 10, 20, 20, 30, 30, 30},
- "",
- },
- {
- "stack ops",
- []byte{
- opPUSHB010, // [10, 20, 30]
- 10,
- 20,
- 30,
- opCLEAR, // []
- opPUSHB010, // [40, 50, 60]
- 40,
- 50,
- 60,
- opSWAP, // [40, 60, 50]
- opDUP, // [40, 60, 50, 50]
- opDUP, // [40, 60, 50, 50, 50]
- opPOP, // [40, 60, 50, 50]
- opDEPTH, // [40, 60, 50, 50, 4]
- opCINDEX, // [40, 60, 50, 50, 40]
- opPUSHB000, // [40, 60, 50, 50, 40, 4]
- 4,
- opMINDEX, // [40, 50, 50, 40, 60]
- },
- []int32{40, 50, 50, 40, 60},
- "",
- },
- {
- "push ops",
- []byte{
- opPUSHB000, // [255]
- 255,
- opPUSHW001, // [255, -2, 253]
- 255,
- 254,
- 0,
- 253,
- opNPUSHB, // [1, -2, 253, 1, 2]
- 2,
- 1,
- 2,
- opNPUSHW, // [1, -2, 253, 1, 2, 0x0405, 0x0607, 0x0809]
- 3,
- 4,
- 5,
- 6,
- 7,
- 8,
- 9,
- },
- []int32{255, -2, 253, 1, 2, 0x0405, 0x0607, 0x0809},
- "",
- },
- {
- "store ops",
- []byte{
- opPUSHB011, // [1, 22, 3, 44]
- 1,
- 22,
- 3,
- 44,
- opWS, // [1, 22]
- opWS, // []
- opPUSHB000, // [3]
- 3,
- opRS, // [44]
- },
- []int32{44},
- "",
- },
- {
- "comparison ops",
- []byte{
- opPUSHB001, // [10, 20]
- 10,
- 20,
- opLT, // [1]
- opPUSHB001, // [1, 10, 20]
- 10,
- 20,
- opLTEQ, // [1, 1]
- opPUSHB001, // [1, 1, 10, 20]
- 10,
- 20,
- opGT, // [1, 1, 0]
- opPUSHB001, // [1, 1, 0, 10, 20]
- 10,
- 20,
- opGTEQ, // [1, 1, 0, 0]
- opEQ, // [1, 1, 1]
- opNEQ, // [1, 0]
- },
- []int32{1, 0},
- "",
- },
- {
- "odd/even",
- // Calculate odd(2+31/64), odd(2+32/64), even(2), even(1).
- []byte{
- opPUSHB000, // [159]
- 159,
- opODD, // [0]
- opPUSHB000, // [0, 160]
- 160,
- opODD, // [0, 1]
- opPUSHB000, // [0, 1, 128]
- 128,
- opEVEN, // [0, 1, 1]
- opPUSHB000, // [0, 1, 1, 64]
- 64,
- opEVEN, // [0, 1, 1, 0]
- },
- []int32{0, 1, 1, 0},
- "",
- },
- {
- "if true",
- []byte{
- opPUSHB001, // [255, 1]
- 255,
- 1,
- opIF,
- opPUSHB000, // [255, 2]
- 2,
- opEIF,
- opPUSHB000, // [255, 2, 254]
- 254,
- },
- []int32{255, 2, 254},
- "",
- },
- {
- "if false",
- []byte{
- opPUSHB001, // [255, 0]
- 255,
- 0,
- opIF,
- opPUSHB000, // [255]
- 2,
- opEIF,
- opPUSHB000, // [255, 254]
- 254,
- },
- []int32{255, 254},
- "",
- },
- {
- "if/else true",
- []byte{
- opPUSHB000, // [1]
- 1,
- opIF,
- opPUSHB000, // [2]
- 2,
- opELSE,
- opPUSHB000, // not executed
- 3,
- opEIF,
- },
- []int32{2},
- "",
- },
- {
- "if/else false",
- []byte{
- opPUSHB000, // [0]
- 0,
- opIF,
- opPUSHB000, // not executed
- 2,
- opELSE,
- opPUSHB000, // [3]
- 3,
- opEIF,
- },
- []int32{3},
- "",
- },
- {
- "if/else true if/else false",
- // 0x58 is the opcode for opIF. The literal 0x58s below are pushed data.
- []byte{
- opPUSHB010, // [255, 0, 1]
- 255,
- 0,
- 1,
- opIF,
- opIF,
- opPUSHB001, // not executed
- 0x58,
- 0x58,
- opELSE,
- opPUSHW000, // [255, 0x5858]
- 0x58,
- 0x58,
- opEIF,
- opELSE,
- opIF,
- opNPUSHB, // not executed
- 3,
- 0x58,
- 0x58,
- 0x58,
- opELSE,
- opNPUSHW, // not executed
- 2,
- 0x58,
- 0x58,
- 0x58,
- 0x58,
- opEIF,
- opEIF,
- opPUSHB000, // [255, 0x5858, 254]
- 254,
- },
- []int32{255, 0x5858, 254},
- "",
- },
- {
- "if/else false if/else true",
- // 0x58 is the opcode for opIF. The literal 0x58s below are pushed data.
- []byte{
- opPUSHB010, // [255, 1, 0]
- 255,
- 1,
- 0,
- opIF,
- opIF,
- opPUSHB001, // not executed
- 0x58,
- 0x58,
- opELSE,
- opPUSHW000, // not executed
- 0x58,
- 0x58,
- opEIF,
- opELSE,
- opIF,
- opNPUSHB, // [255, 0x58, 0x58, 0x58]
- 3,
- 0x58,
- 0x58,
- 0x58,
- opELSE,
- opNPUSHW, // not executed
- 2,
- 0x58,
- 0x58,
- 0x58,
- 0x58,
- opEIF,
- opEIF,
- opPUSHB000, // [255, 0x58, 0x58, 0x58, 254]
- 254,
- },
- []int32{255, 0x58, 0x58, 0x58, 254},
- "",
- },
- {
- "logical ops",
- []byte{
- opPUSHB010, // [0, 10, 20]
- 0,
- 10,
- 20,
- opAND, // [0, 1]
- opOR, // [1]
- opNOT, // [0]
- },
- []int32{0},
- "",
- },
- {
- "arithmetic ops",
- // Calculate abs((-(1 - (2*3)))/2 + 1/64).
- // The answer is 5/2 + 1/64 in ideal numbers, or 161 in 26.6 fixed point math.
- []byte{
- opPUSHB010, // [64, 128, 192]
- 1 << 6,
- 2 << 6,
- 3 << 6,
- opMUL, // [64, 384]
- opSUB, // [-320]
- opNEG, // [320]
- opPUSHB000, // [320, 128]
- 2 << 6,
- opDIV, // [160]
- opPUSHB000, // [160, 1]
- 1,
- opADD, // [161]
- opABS, // [161]
- },
- []int32{161},
- "",
- },
- {
- "floor, ceiling",
- []byte{
- opPUSHB000, // [96]
- 96,
- opFLOOR, // [64]
- opPUSHB000, // [64, 96]
- 96,
- opCEILING, // [64, 128]
- },
- []int32{64, 128},
- "",
- },
- {
- "rounding",
- // Round 1.40625 (which is 90/64) under various rounding policies.
- // See figure 20 of https://developer.apple.com/fonts/TTRefMan/RM02/Chap2.html#rounding
- []byte{
- opROFF, // []
- opPUSHB000, // [90]
- 90,
- opROUND00, // [90]
- opRTG, // [90]
- opPUSHB000, // [90, 90]
- 90,
- opROUND00, // [90, 64]
- opRTHG, // [90, 64]
- opPUSHB000, // [90, 64, 90]
- 90,
- opROUND00, // [90, 64, 96]
- opRDTG, // [90, 64, 96]
- opPUSHB000, // [90, 64, 96, 90]
- 90,
- opROUND00, // [90, 64, 96, 64]
- opRUTG, // [90, 64, 96, 64]
- opPUSHB000, // [90, 64, 96, 64, 90]
- 90,
- opROUND00, // [90, 64, 96, 64, 128]
- opRTDG, // [90, 64, 96, 64, 128]
- opPUSHB000, // [90, 64, 96, 64, 128, 90]
- 90,
- opROUND00, // [90, 64, 96, 64, 128, 96]
- },
- []int32{90, 64, 96, 64, 128, 96},
- "",
- },
- {
- "super-rounding",
- // See figure 20 of https://developer.apple.com/fonts/TTRefMan/RM02/Chap2.html#rounding
- // and the sign preservation steps of the "Order of rounding operations" section.
- []byte{
- opPUSHB000, // [0x58]
- 0x58,
- opSROUND, // []
- opPUSHW000, // [-81]
- 0xff,
- 0xaf,
- opROUND00, // [-80]
- opPUSHW000, // [-80, -80]
- 0xff,
- 0xb0,
- opROUND00, // [-80, -80]
- opPUSHW000, // [-80, -80, -17]
- 0xff,
- 0xef,
- opROUND00, // [-80, -80, -16]
- opPUSHW000, // [-80, -80, -16, -16]
- 0xff,
- 0xf0,
- opROUND00, // [-80, -80, -16, -16]
- opPUSHB000, // [-80, -80, -16, -16, 0]
- 0,
- opROUND00, // [-80, -80, -16, -16, 16]
- opPUSHB000, // [-80, -80, -16, -16, 16, 16]
- 16,
- opROUND00, // [-80, -80, -16, -16, 16, 16]
- opPUSHB000, // [-80, -80, -16, -16, 16, 16, 47]
- 47,
- opROUND00, // [-80, -80, -16, -16, 16, 16, 16]
- opPUSHB000, // [-80, -80, -16, -16, 16, 16, 16, 48]
- 48,
- opROUND00, // [-80, -80, -16, -16, 16, 16, 16, 80]
- },
- []int32{-80, -80, -16, -16, 16, 16, 16, 80},
- "",
- },
- {
- "roll",
- []byte{
- opPUSHB010, // [1, 2, 3]
- 1,
- 2,
- 3,
- opROLL, // [2, 3, 1]
- },
- []int32{2, 3, 1},
- "",
- },
- {
- "max/min",
- []byte{
- opPUSHW001, // [-2, -3]
- 0xff,
- 0xfe,
- 0xff,
- 0xfd,
- opMAX, // [-2]
- opPUSHW001, // [-2, -4, -5]
- 0xff,
- 0xfc,
- 0xff,
- 0xfb,
- opMIN, // [-2, -5]
- },
- []int32{-2, -5},
- "",
- },
- {
- "functions",
- []byte{
- opPUSHB011, // [3, 7, 0, 3]
- 3,
- 7,
- 0,
- 3,
-
- opFDEF, // Function #3 (not called)
- opPUSHB000,
- 98,
- opENDF,
-
- opFDEF, // Function #0
- opDUP,
- opADD,
- opENDF,
-
- opFDEF, // Function #7
- opPUSHB001,
- 10,
- 0,
- opCALL,
- opDUP,
- opENDF,
-
- opFDEF, // Function #3 (again)
- opPUSHB000,
- 99,
- opENDF,
-
- opPUSHB001, // [2, 0]
- 2,
- 0,
- opCALL, // [4]
- opPUSHB000, // [4, 3]
- 3,
- opLOOPCALL, // [99, 99, 99, 99]
- opPUSHB000, // [99, 99, 99, 99, 7]
- 7,
- opCALL, // [99, 99, 99, 99, 20, 20]
- },
- []int32{99, 99, 99, 99, 20, 20},
- "",
- },
- }
-
- for _, tc := range testCases {
- h := &hinter{}
- h.init(&Font{
- maxStorage: 32,
- maxStackElements: 100,
- }, 768)
- err, errStr := h.run(tc.prog, nil, nil, nil, nil), ""
- if err != nil {
- errStr = err.Error()
- }
- if tc.errStr != "" {
- if errStr == "" {
- t.Errorf("%s: got no error, want %q", tc.desc, tc.errStr)
- } else if !strings.Contains(errStr, tc.errStr) {
- t.Errorf("%s: got error %q, want one containing %q", tc.desc, errStr, tc.errStr)
- }
- continue
- }
- if errStr != "" {
- t.Errorf("%s: got error %q, want none", tc.desc, errStr)
- continue
- }
- got := h.stack[:len(tc.want)]
- if !reflect.DeepEqual(got, tc.want) {
- t.Errorf("%s: got %v, want %v", tc.desc, got, tc.want)
- continue
- }
- }
-}
-
-// TestMove tests that the hinter.move method matches the output of the C
-// Freetype implementation.
-func TestMove(t *testing.T) {
- h, p := hinter{}, Point{}
- testCases := []struct {
- pvX, pvY, fvX, fvY f2dot14
- wantX, wantY fixed.Int26_6
- }{
- {+0x4000, +0x0000, +0x4000, +0x0000, +1000, +0},
- {+0x4000, +0x0000, -0x4000, +0x0000, +1000, +0},
- {-0x4000, +0x0000, +0x4000, +0x0000, -1000, +0},
- {-0x4000, +0x0000, -0x4000, +0x0000, -1000, +0},
- {+0x0000, +0x4000, +0x0000, +0x4000, +0, +1000},
- {+0x0000, +0x4000, +0x0000, -0x4000, +0, +1000},
- {+0x4000, +0x0000, +0x2d41, +0x2d41, +1000, +1000},
- {+0x4000, +0x0000, -0x2d41, +0x2d41, +1000, -1000},
- {+0x4000, +0x0000, +0x2d41, -0x2d41, +1000, -1000},
- {+0x4000, +0x0000, -0x2d41, -0x2d41, +1000, +1000},
- {-0x4000, +0x0000, +0x2d41, +0x2d41, -1000, -1000},
- {-0x4000, +0x0000, -0x2d41, +0x2d41, -1000, +1000},
- {-0x4000, +0x0000, +0x2d41, -0x2d41, -1000, +1000},
- {-0x4000, +0x0000, -0x2d41, -0x2d41, -1000, -1000},
- {+0x376d, +0x2000, +0x2d41, +0x2d41, +732, +732},
- {-0x376d, +0x2000, +0x2d41, +0x2d41, -2732, -2732},
- {+0x376d, +0x2000, +0x2d41, -0x2d41, +2732, -2732},
- {-0x376d, +0x2000, +0x2d41, -0x2d41, -732, +732},
- {-0x376d, -0x2000, +0x2d41, +0x2d41, -732, -732},
- {+0x376d, +0x2000, +0x4000, +0x0000, +1155, +0},
- {+0x376d, +0x2000, +0x0000, +0x4000, +0, +2000},
- }
- for _, tc := range testCases {
- p = Point{}
- h.gs.pv = [2]f2dot14{tc.pvX, tc.pvY}
- h.gs.fv = [2]f2dot14{tc.fvX, tc.fvY}
- h.move(&p, 1000, true)
- tx := p.Flags&flagTouchedX != 0
- ty := p.Flags&flagTouchedY != 0
- wantTX := tc.fvX != 0
- wantTY := tc.fvY != 0
- if p.X != tc.wantX || p.Y != tc.wantY || tx != wantTX || ty != wantTY {
- t.Errorf("pv=%v, fv=%v\ngot %d, %d, %t, %t\nwant %d, %d, %t, %t",
- h.gs.pv, h.gs.fv, p.X, p.Y, tx, ty, tc.wantX, tc.wantY, wantTX, wantTY)
- continue
- }
-
- // Check that p is aligned with the freedom vector.
- a := int64(p.X) * int64(tc.fvY)
- b := int64(p.Y) * int64(tc.fvX)
- if a != b {
- t.Errorf("pv=%v, fv=%v, p=%v not aligned with fv", h.gs.pv, h.gs.fv, p)
- continue
- }
-
- // Check that the projected p is 1000 away from the origin.
- dotProd := (int64(p.X)*int64(tc.pvX) + int64(p.Y)*int64(tc.pvY) + 1<<13) >> 14
- if dotProd != 1000 {
- t.Errorf("pv=%v, fv=%v, p=%v not 1000 from origin", h.gs.pv, h.gs.fv, p)
- continue
- }
- }
-}
-
-// TestNormalize tests that the normalize function matches the output of the C
-// Freetype implementation.
-func TestNormalize(t *testing.T) {
- testCases := [][2]f2dot14{
- {-15895, 3974},
- {-15543, 5181},
- {-14654, 7327},
- {-11585, 11585},
- {0, 16384},
- {11585, 11585},
- {14654, 7327},
- {15543, 5181},
- {15895, 3974},
- {16066, 3213},
- {16161, 2694},
- {16219, 2317},
- {16257, 2032},
- {16284, 1809},
- }
- for i, want := range testCases {
- got := normalize(f2dot14(i)-4, 1)
- if got != want {
- t.Errorf("i=%d: got %v, want %v", i, got, want)
- }
- }
-}
diff --git a/Godeps/_workspace/src/github.com/golang/freetype/truetype/truetype_test.go b/Godeps/_workspace/src/github.com/golang/freetype/truetype/truetype_test.go
deleted file mode 100644
index bd62d1da1..000000000
--- a/Godeps/_workspace/src/github.com/golang/freetype/truetype/truetype_test.go
+++ /dev/null
@@ -1,400 +0,0 @@
-// Copyright 2012 The Freetype-Go Authors. All rights reserved.
-// Use of this source code is governed by your choice of either the
-// FreeType License or the GNU General Public License version 2 (or
-// any later version), both of which can be found in the LICENSE file.
-
-package truetype
-
-import (
- "bufio"
- "fmt"
- "io"
- "io/ioutil"
- "os"
- "strconv"
- "strings"
- "testing"
-
- "golang.org/x/image/font"
- "golang.org/x/image/math/fixed"
-)
-
-func parseTestdataFont(name string) (f *Font, testdataIsOptional bool, err error) {
- b, err := ioutil.ReadFile(fmt.Sprintf("../testdata/%s.ttf", name))
- if err != nil {
- // The "x-foo" fonts are optional tests, as they are not checked
- // in for copyright or file size reasons.
- return nil, strings.HasPrefix(name, "x-"), fmt.Errorf("%s: ReadFile: %v", name, err)
- }
- f, err = Parse(b)
- if err != nil {
- return nil, true, fmt.Errorf("%s: Parse: %v", name, err)
- }
- return f, false, nil
-}
-
-func mkBounds(minX, minY, maxX, maxY fixed.Int26_6) fixed.Rectangle26_6 {
- return fixed.Rectangle26_6{
- Min: fixed.Point26_6{
- X: minX,
- Y: minY,
- },
- Max: fixed.Point26_6{
- X: maxX,
- Y: maxY,
- },
- }
-}
-
-// TestParse tests that the luxisr.ttf metrics and glyphs are parsed correctly.
-// The numerical values can be manually verified by examining luxisr.ttx.
-func TestParse(t *testing.T) {
- f, _, err := parseTestdataFont("luxisr")
- if err != nil {
- t.Fatal(err)
- }
- if got, want := f.FUnitsPerEm(), int32(2048); got != want {
- t.Errorf("FUnitsPerEm: got %v, want %v", got, want)
- }
- fupe := fixed.Int26_6(f.FUnitsPerEm())
- if got, want := f.Bounds(fupe), mkBounds(-441, -432, 2024, 2033); got != want {
- t.Errorf("Bounds: got %v, want %v", got, want)
- }
-
- i0 := f.Index('A')
- i1 := f.Index('V')
- if i0 != 36 || i1 != 57 {
- t.Fatalf("Index: i0, i1 = %d, %d, want 36, 57", i0, i1)
- }
- if got, want := f.HMetric(fupe, i0), (HMetric{1366, 19}); got != want {
- t.Errorf("HMetric: got %v, want %v", got, want)
- }
- if got, want := f.VMetric(fupe, i0), (VMetric{2465, 553}); got != want {
- t.Errorf("VMetric: got %v, want %v", got, want)
- }
- if got, want := f.Kern(fupe, i0, i1), fixed.Int26_6(-144); got != want {
- t.Errorf("Kern: got %v, want %v", got, want)
- }
-
- g := &GlyphBuf{}
- err = g.Load(f, fupe, i0, font.HintingNone)
- if err != nil {
- t.Fatalf("Load: %v", err)
- }
- g0 := &GlyphBuf{
- Bounds: g.Bounds,
- Points: g.Points,
- Ends: g.Ends,
- }
- g1 := &GlyphBuf{
- Bounds: mkBounds(19, 0, 1342, 1480),
- Points: []Point{
- {19, 0, 51},
- {581, 1480, 1},
- {789, 1480, 51},
- {1342, 0, 1},
- {1116, 0, 35},
- {962, 410, 3},
- {368, 410, 33},
- {214, 0, 3},
- {428, 566, 19},
- {904, 566, 33},
- {667, 1200, 3},
- },
- Ends: []int{8, 11},
- }
- if got, want := fmt.Sprint(g0), fmt.Sprint(g1); got != want {
- t.Errorf("GlyphBuf:\ngot %v\nwant %v", got, want)
- }
-}
-
-func TestIndex(t *testing.T) {
- testCases := map[string]map[rune]Index{
- "luxisr": {
- ' ': 3,
- '!': 4,
- 'A': 36,
- 'V': 57,
- 'É': 101,
- 'fl': 193,
- '\u22c5': 385,
- '中': 0,
- },
-
- // The x-etc test cases use those versions of the .ttf files provided
- // by Ubuntu 14.04. See testdata/make-other-hinting-txts.sh for details.
-
- "x-arial-bold": {
- ' ': 3,
- '+': 14,
- '0': 19,
- '_': 66,
- 'w': 90,
- '~': 97,
- 'Ä': 98,
- 'fl': 192,
- '½': 242,
- 'σ': 305,
- 'λ': 540,
- 'ỹ': 1275,
- '\u04e9': 1319,
- '中': 0,
- },
- "x-deja-vu-sans-oblique": {
- ' ': 3,
- '*': 13,
- 'Œ': 276,
- 'ω': 861,
- '‡': 2571,
- '⊕': 3110,
- 'fl': 4728,
- '\ufb03': 4729,
- '\ufffd': 4813,
- // TODO: '\U0001f640': ???,
- '中': 0,
- },
- "x-droid-sans-japanese": {
- ' ': 0,
- '\u3000': 3,
- '\u3041': 25,
- '\u30fe': 201,
- '\uff61': 202,
- '\uff67': 208,
- '\uff9e': 263,
- '\uff9f': 264,
- '\u4e00': 265,
- '\u557e': 1000,
- '\u61b6': 2024,
- '\u6ede': 3177,
- '\u7505': 3555,
- '\u81e3': 4602,
- '\u81e5': 4603,
- '\u81e7': 4604,
- '\u81e8': 4605,
- '\u81ea': 4606,
- '\u81ed': 4607,
- '\u81f3': 4608,
- '\u81f4': 4609,
- '\u91c7': 5796,
- '\u9fa0': 6620,
- '\u203e': 12584,
- },
- "x-times-new-roman": {
- ' ': 3,
- ':': 29,
- 'fl': 192,
- 'Ŀ': 273,
- '♠': 388,
- 'Ŗ': 451,
- 'Σ': 520,
- '\u200D': 745,
- 'Ẽ': 1216,
- '\u04e9': 1319,
- '中': 0,
- },
- }
- for name, wants := range testCases {
- f, testdataIsOptional, err := parseTestdataFont(name)
- if err != nil {
- if testdataIsOptional {
- t.Log(err)
- } else {
- t.Fatal(err)
- }
- continue
- }
- for r, want := range wants {
- if got := f.Index(r); got != want {
- t.Errorf("%s: Index of %q, aka %U: got %d, want %d", name, r, r, got, want)
- }
- }
- }
-}
-
-func TestName(t *testing.T) {
- testCases := map[string]string{
- "luximr": "Luxi Mono",
- "luxirr": "Luxi Serif",
- "luxisr": "Luxi Sans",
- }
-
- for name, want := range testCases {
- f, testdataIsOptional, err := parseTestdataFont(name)
- if err != nil {
- if testdataIsOptional {
- t.Log(err)
- } else {
- t.Fatal(err)
- }
- continue
- }
- if got := f.Name(NameIDFontFamily); got != want {
- t.Errorf("%s: got %q, want %q", name, got, want)
- }
- }
-}
-
-type scalingTestData struct {
- advanceWidth fixed.Int26_6
- bounds fixed.Rectangle26_6
- points []Point
-}
-
-// scalingTestParse parses a line of points like
-// 213 -22 -111 236 555;-22 -111 1, 178 555 1, 236 555 1, 36 -111 1
-// The line will not have a trailing "\n".
-func scalingTestParse(line string) (ret scalingTestData) {
- next := func(s string) (string, fixed.Int26_6) {
- t, i := "", strings.Index(s, " ")
- if i != -1 {
- s, t = s[:i], s[i+1:]
- }
- x, _ := strconv.Atoi(s)
- return t, fixed.Int26_6(x)
- }
-
- i := strings.Index(line, ";")
- prefix, line := line[:i], line[i+1:]
-
- prefix, ret.advanceWidth = next(prefix)
- prefix, ret.bounds.Min.X = next(prefix)
- prefix, ret.bounds.Min.Y = next(prefix)
- prefix, ret.bounds.Max.X = next(prefix)
- prefix, ret.bounds.Max.Y = next(prefix)
-
- ret.points = make([]Point, 0, 1+strings.Count(line, ","))
- for len(line) > 0 {
- s := line
- if i := strings.Index(line, ","); i != -1 {
- s, line = line[:i], line[i+1:]
- for len(line) > 0 && line[0] == ' ' {
- line = line[1:]
- }
- } else {
- line = ""
- }
- s, x := next(s)
- s, y := next(s)
- s, f := next(s)
- ret.points = append(ret.points, Point{X: x, Y: y, Flags: uint32(f)})
- }
- return ret
-}
-
-// scalingTestEquals is equivalent to, but faster than, calling
-// reflect.DeepEquals(a, b), and also returns the index of the first non-equal
-// element. It also treats a nil []Point and an empty non-nil []Point as equal.
-// a and b must have equal length.
-func scalingTestEquals(a, b []Point) (index int, equals bool) {
- for i, p := range a {
- if p != b[i] {
- return i, false
- }
- }
- return 0, true
-}
-
-var scalingTestCases = []struct {
- name string
- size int
-}{
- {"luxisr", 12},
- {"x-arial-bold", 11},
- {"x-deja-vu-sans-oblique", 17},
- {"x-droid-sans-japanese", 9},
- {"x-times-new-roman", 13},
-}
-
-func testScaling(t *testing.T, h font.Hinting) {
- for _, tc := range scalingTestCases {
- f, testdataIsOptional, err := parseTestdataFont(tc.name)
- if err != nil {
- if testdataIsOptional {
- t.Log(err)
- } else {
- t.Error(err)
- }
- continue
- }
- hintingStr := "sans"
- if h != font.HintingNone {
- hintingStr = "with"
- }
- testFile, err := os.Open(fmt.Sprintf(
- "../testdata/%s-%dpt-%s-hinting.txt", tc.name, tc.size, hintingStr))
- if err != nil {
- t.Errorf("%s: Open: %v", tc.name, err)
- continue
- }
- defer testFile.Close()
-
- wants := []scalingTestData{}
- scanner := bufio.NewScanner(testFile)
- if scanner.Scan() {
- major, minor, patch := 0, 0, 0
- _, err := fmt.Sscanf(scanner.Text(), "freetype version %d.%d.%d", &major, &minor, &patch)
- if err != nil {
- t.Errorf("%s: version information: %v", tc.name, err)
- }
- if (major < 2) || (major == 2 && minor < 5) || (major == 2 && minor == 5 && patch < 1) {
- t.Errorf("%s: need freetype version >= 2.5.1.\n"+
- "Try setting LD_LIBRARY_PATH=/path/to/freetype_built_from_src/objs/.libs/\n"+
- "and re-running testdata/make-other-hinting-txts.sh",
- tc.name)
- continue
- }
- } else {
- t.Errorf("%s: no version information", tc.name)
- continue
- }
- for scanner.Scan() {
- wants = append(wants, scalingTestParse(scanner.Text()))
- }
- if err := scanner.Err(); err != nil && err != io.EOF {
- t.Errorf("%s: Scanner: %v", tc.name, err)
- continue
- }
-
- glyphBuf := &GlyphBuf{}
- for i, want := range wants {
- if err = glyphBuf.Load(f, fixed.I(tc.size), Index(i), h); err != nil {
- t.Errorf("%s: glyph #%d: Load: %v", tc.name, i, err)
- continue
- }
- got := scalingTestData{
- advanceWidth: glyphBuf.AdvanceWidth,
- bounds: glyphBuf.Bounds,
- points: glyphBuf.Points,
- }
-
- if got.advanceWidth != want.advanceWidth {
- t.Errorf("%s: glyph #%d advance width:\ngot %v\nwant %v",
- tc.name, i, got.advanceWidth, want.advanceWidth)
- continue
- }
-
- if got.bounds != want.bounds {
- t.Errorf("%s: glyph #%d bounds:\ngot %v\nwant %v",
- tc.name, i, got.bounds, want.bounds)
- continue
- }
-
- for i := range got.points {
- got.points[i].Flags &= 0x01
- }
- if len(got.points) != len(want.points) {
- t.Errorf("%s: glyph #%d:\ngot %v\nwant %v\ndifferent slice lengths: %d versus %d",
- tc.name, i, got.points, want.points, len(got.points), len(want.points))
- continue
- }
- if j, equals := scalingTestEquals(got.points, want.points); !equals {
- t.Errorf("%s: glyph #%d:\ngot %v\nwant %v\nat index %d: %v versus %v",
- tc.name, i, got.points, want.points, j, got.points[j], want.points[j])
- continue
- }
- }
- }
-}
-
-func TestScalingHintingNone(t *testing.T) { testScaling(t, font.HintingNone) }
-func TestScalingHintingFull(t *testing.T) { testScaling(t, font.HintingFull) }