aboutsummaryrefslogtreecommitdiff
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
parent500caaeda74dd9c660279036293f4b2997cf0b03 (diff)
Update vendor
-rw-r--r--Gopkg.lock14
-rw-r--r--vendor/github.com/llgcode/draw2d/draw2dbase/curve.go35
-rw-r--r--vendor/github.com/llgcode/draw2d/draw2dbase/curve_test.go42
-rw-r--r--vendor/github.com/llgcode/draw2d/draw2dbase/text.go45
-rw-r--r--vendor/github.com/llgcode/draw2d/draw2dgl/gc.go26
-rw-r--r--vendor/github.com/llgcode/draw2d/draw2dimg/curve_limit_test.go189
-rw-r--r--vendor/github.com/llgcode/draw2d/draw2dimg/ftgc.go24
-rw-r--r--vendor/github.com/llgcode/draw2d/font.go93
-rw-r--r--vendor/github.com/llgcode/draw2d/output/samples/geometry.pngbin24841 -> 23028 bytes
-rw-r--r--vendor/github.com/llgcode/draw2d/output/samples/postscript.pngbin41596 -> 43560 bytes
-rw-r--r--vendor/github.com/llgcode/draw2d/sync_test.go46
-rw-r--r--vendor/golang.org/x/image/README3
-rw-r--r--vendor/golang.org/x/image/README.md17
-rw-r--r--vendor/golang.org/x/image/draw/gen.go5
-rw-r--r--vendor/golang.org/x/image/draw/impl.go10
-rw-r--r--vendor/golang.org/x/image/draw/scale_test.go11
-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
21 files changed, 764 insertions, 77 deletions
diff --git a/Gopkg.lock b/Gopkg.lock
index 1fb7328..bd30828 100644
--- a/Gopkg.lock
+++ b/Gopkg.lock
@@ -4,7 +4,10 @@
[[projects]]
branch = "master"
name = "github.com/golang/freetype"
- packages = ["raster","truetype"]
+ packages = [
+ "raster",
+ "truetype"
+ ]
revision = "e2365dfdc4a05e4b8299a783240d4a7d5a65d4e4"
[[projects]]
@@ -17,7 +20,7 @@
branch = "master"
name = "github.com/llgcode/draw2d"
packages = ["."]
- revision = "dcbfbe505d35de8166ccfc47ff9e4bb020473e18"
+ revision = "c41aa97d30ae131f178c555e3bbaeae333dc8f0d"
[[projects]]
branch = "master"
@@ -28,8 +31,11 @@
[[projects]]
branch = "master"
name = "golang.org/x/image"
- packages = ["font","math/fixed"]
- revision = "e20db36d77bd0cb36cea8fe49d5c37d82d21591f"
+ packages = [
+ "font",
+ "math/fixed"
+ ]
+ revision = "12117c17ca67ffa1ce22e9409f3b0b0a93ac08c7"
[solve-meta]
analyzer-name = "dep"
diff --git a/vendor/github.com/llgcode/draw2d/draw2dbase/curve.go b/vendor/github.com/llgcode/draw2d/draw2dbase/curve.go
index 211e107..05a9ede 100644
--- a/vendor/github.com/llgcode/draw2d/draw2dbase/curve.go
+++ b/vendor/github.com/llgcode/draw2d/draw2dbase/curve.go
@@ -4,6 +4,7 @@
package draw2dbase
import (
+ "errors"
"math"
)
@@ -17,6 +18,7 @@ const (
// SubdivideCubic a Bezier cubic curve in 2 equivalents Bezier cubic curves.
// c1 and c2 parameters are the resulting curves
+// length of c, c1 and c2 must be 8 otherwise it panics.
func SubdivideCubic(c, c1, c2 []float64) {
// First point of c is the first point of c1
c1[0], c1[1] = c[0], c[1]
@@ -48,7 +50,10 @@ func SubdivideCubic(c, c1, c2 []float64) {
// TraceCubic generate lines subdividing the cubic curve using a Liner
// flattening_threshold helps determines the flattening expectation of the curve
-func TraceCubic(t Liner, cubic []float64, flatteningThreshold float64) {
+func TraceCubic(t Liner, cubic []float64, flatteningThreshold float64) error {
+ if len(cubic) < 8 {
+ return errors.New("cubic length must be >= 8")
+ }
// Allocation curves
var curves [CurveRecursionLimit * 8]float64
copy(curves[0:8], cubic[0:8])
@@ -60,7 +65,7 @@ func TraceCubic(t Liner, cubic []float64, flatteningThreshold float64) {
var dx, dy, d2, d3 float64
for i >= 0 {
- c = curves[i*8:]
+ c = curves[i:]
dx = c[6] - c[0]
dy = c[7] - c[1]
@@ -68,15 +73,16 @@ func TraceCubic(t Liner, cubic []float64, flatteningThreshold float64) {
d3 = math.Abs((c[4]-c[6])*dy - (c[5]-c[7])*dx)
// if it's flat then trace a line
- if (d2+d3)*(d2+d3) < flatteningThreshold*(dx*dx+dy*dy) || i == len(curves)-1 {
+ if (d2+d3)*(d2+d3) <= flatteningThreshold*(dx*dx+dy*dy) || i == len(curves)-8 {
t.LineTo(c[6], c[7])
- i--
+ i -= 8
} else {
// second half of bezier go lower onto the stack
- SubdivideCubic(c, curves[(i+1)*8:], curves[i*8:])
- i++
+ SubdivideCubic(c, curves[i+8:], curves[i:])
+ i += 8
}
}
+ return nil
}
// Quad
@@ -84,6 +90,7 @@ func TraceCubic(t Liner, cubic []float64, flatteningThreshold float64) {
// SubdivideQuad a Bezier quad curve in 2 equivalents Bezier quad curves.
// c1 and c2 parameters are the resulting curves
+// length of c, c1 and c2 must be 6 otherwise it panics.
func SubdivideQuad(c, c1, c2 []float64) {
// First point of c is the first point of c1
c1[0], c1[1] = c[0], c[1]
@@ -103,7 +110,10 @@ func SubdivideQuad(c, c1, c2 []float64) {
// TraceQuad generate lines subdividing the curve using a Liner
// flattening_threshold helps determines the flattening expectation of the curve
-func TraceQuad(t Liner, quad []float64, flatteningThreshold float64) {
+func TraceQuad(t Liner, quad []float64, flatteningThreshold float64) error {
+ if len(quad) < 6 {
+ return errors.New("quad length must be >= 6")
+ }
// Allocates curves stack
var curves [CurveRecursionLimit * 6]float64
copy(curves[0:6], quad[0:6])
@@ -113,22 +123,23 @@ func TraceQuad(t Liner, quad []float64, flatteningThreshold float64) {
var dx, dy, d float64
for i >= 0 {
- c = curves[i*6:]
+ c = curves[i:]
dx = c[4] - c[0]
dy = c[5] - c[1]
d = math.Abs(((c[2]-c[4])*dy - (c[3]-c[5])*dx))
// if it's flat then trace a line
- if (d*d) < flatteningThreshold*(dx*dx+dy*dy) || i == len(curves)-1 {
+ if (d*d) <= flatteningThreshold*(dx*dx+dy*dy) || i == len(curves)-6 {
t.LineTo(c[4], c[5])
- i--
+ i -= 6
} else {
// second half of bezier go lower onto the stack
- SubdivideQuad(c, curves[(i+1)*6:], curves[i*6:])
- i++
+ SubdivideQuad(c, curves[i+6:], curves[i:])
+ i += 6
}
}
+ return nil
}
// TraceArc trace an arc using a Liner
diff --git a/vendor/github.com/llgcode/draw2d/draw2dbase/curve_test.go b/vendor/github.com/llgcode/draw2d/draw2dbase/curve_test.go
index fa954df..fc4efc8 100644
--- a/vendor/github.com/llgcode/draw2d/draw2dbase/curve_test.go
+++ b/vendor/github.com/llgcode/draw2d/draw2dbase/curve_test.go
@@ -101,6 +101,32 @@ func TestQuadCurve(t *testing.T) {
fmt.Println()
}
+func TestQuadCurveCombinedPoint(t *testing.T) {
+ var p1 SegmentedPath
+ TraceQuad(&p1, []float64{0, 0, 0, 0, 0, 0}, flatteningThreshold)
+ if len(p1.Points) != 2 {
+ t.Error("It must have one point for this curve", len(p1.Points))
+ }
+ var p2 SegmentedPath
+ TraceQuad(&p2, []float64{0, 0, 100, 100, 0, 0}, flatteningThreshold)
+ if len(p2.Points) != 2 {
+ t.Error("It must have one point for this curve", len(p2.Points))
+ }
+}
+
+func TestCubicCurveCombinedPoint(t *testing.T) {
+ var p1 SegmentedPath
+ TraceCubic(&p1, []float64{0, 0, 0, 0, 0, 0, 0, 0}, flatteningThreshold)
+ if len(p1.Points) != 2 {
+ t.Error("It must have one point for this curve", len(p1.Points))
+ }
+ var p2 SegmentedPath
+ TraceCubic(&p2, []float64{0, 0, 100, 100, 200, 200, 0, 0}, flatteningThreshold)
+ if len(p2.Points) != 2 {
+ t.Error("It must have one point for this curve", len(p2.Points))
+ }
+}
+
func BenchmarkCubicCurve(b *testing.B) {
for i := 0; i < b.N; i++ {
for i := 0; i < len(testsCubicFloat64); i += 8 {
@@ -132,3 +158,19 @@ func SaveToPngFile(filePath string, m image.Image) error {
}
return nil
}
+
+func TestOutOfRangeTraceCurve(t *testing.T) {
+ c := []float64{
+ 100, 100, 200, 100, 100, 200,
+ }
+ var p SegmentedPath
+ TraceCubic(&p, c, flatteningThreshold)
+}
+
+func TestOutOfRangeTraceQuad(t *testing.T) {
+ c := []float64{
+ 100, 100, 200, 100,
+ }
+ var p SegmentedPath
+ TraceQuad(&p, c, flatteningThreshold)
+}
diff --git a/vendor/github.com/llgcode/draw2d/draw2dbase/text.go b/vendor/github.com/llgcode/draw2d/draw2dbase/text.go
index 4283bad..22b7acf 100644
--- a/vendor/github.com/llgcode/draw2d/draw2dbase/text.go
+++ b/vendor/github.com/llgcode/draw2d/draw2dbase/text.go
@@ -2,21 +2,35 @@ package draw2dbase
import "github.com/llgcode/draw2d"
-var glyphCache map[string]map[rune]*Glyph
+// GlyphCache manage a cache of glyphs
+type GlyphCache interface {
+ // Fetch fetches a glyph from the cache, storing with Render first if it doesn't already exist
+ Fetch(gc draw2d.GraphicContext, fontName string, chr rune) *Glyph
+}
+
+// GlyphCacheImp manage a map of glyphs without sync mecanism, not thread safe
+type GlyphCacheImp struct {
+ glyphs map[string]map[rune]*Glyph
+}
-func init() {
- glyphCache = make(map[string]map[rune]*Glyph)
+
+// NewGlyphCache initializes a GlyphCache
+func NewGlyphCache() *GlyphCacheImp {
+ glyphs := make(map[string]map[rune]*Glyph)
+ return &GlyphCacheImp {
+ glyphs: glyphs,
+ }
}
-// FetchGlyph fetches a glyph from the cache, calling renderGlyph first if it doesn't already exist
-func FetchGlyph(gc draw2d.GraphicContext, fontName string, chr rune) *Glyph {
- if glyphCache[fontName] == nil {
- glyphCache[fontName] = make(map[rune]*Glyph, 60)
+// Fetch fetches a glyph from the cache, calling renderGlyph first if it doesn't already exist
+func (glyphCache *GlyphCacheImp) Fetch(gc draw2d.GraphicContext, fontName string, chr rune) *Glyph {
+ if glyphCache.glyphs[fontName] == nil {
+ glyphCache.glyphs[fontName] = make(map[rune]*Glyph, 60)
}
- if glyphCache[fontName][chr] == nil {
- glyphCache[fontName][chr] = renderGlyph(gc, fontName, chr)
+ if glyphCache.glyphs[fontName][chr] == nil {
+ glyphCache.glyphs[fontName][chr] = renderGlyph(gc, fontName, chr)
}
- return glyphCache[fontName][chr].Copy()
+ return glyphCache.glyphs[fontName][chr].Copy()
}
// renderGlyph renders a glyph then caches and returns it
@@ -27,7 +41,7 @@ func renderGlyph(gc draw2d.GraphicContext, fontName string, chr rune) *Glyph {
width := gc.CreateStringPath(string(chr), 0, 0)
path := gc.GetPath()
return &Glyph{
- path: &path,
+ Path: &path,
Width: width,
}
}
@@ -35,14 +49,15 @@ func renderGlyph(gc draw2d.GraphicContext, fontName string, chr rune) *Glyph {
// Glyph represents a rune which has been converted to a Path and width
type Glyph struct {
// path represents a glyph, it is always at (0, 0)
- path *draw2d.Path
+ Path *draw2d.Path
// Width of the glyph
Width float64
}
+// Copy Returns a copy of a Glyph
func (g *Glyph) Copy() *Glyph {
return &Glyph{
- path: g.path.Copy(),
+ Path: g.Path.Copy(),
Width: g.Width,
}
}
@@ -52,7 +67,7 @@ func (g *Glyph) Fill(gc draw2d.GraphicContext, x, y float64) float64 {
gc.Save()
gc.BeginPath()
gc.Translate(x, y)
- gc.Fill(g.path)
+ gc.Fill(g.Path)
gc.Restore()
return g.Width
}
@@ -62,7 +77,7 @@ func (g *Glyph) Stroke(gc draw2d.GraphicContext, x, y float64) float64 {
gc.Save()
gc.BeginPath()
gc.Translate(x, y)
- gc.Stroke(g.path)
+ gc.Stroke(g.Path)
gc.Restore()
return g.Width
}
diff --git a/vendor/github.com/llgcode/draw2d/draw2dgl/gc.go b/vendor/github.com/llgcode/draw2d/draw2dgl/gc.go
index d512ccc..7253170 100644
--- a/vendor/github.com/llgcode/draw2d/draw2dgl/gc.go
+++ b/vendor/github.com/llgcode/draw2d/draw2dgl/gc.go
@@ -1,7 +1,6 @@
package draw2dgl
import (
- "errors"
"image"
"image/color"
"image/draw"
@@ -125,8 +124,10 @@ type GraphicContext struct {
painter *Painter
fillRasterizer *raster.Rasterizer
strokeRasterizer *raster.Rasterizer
+ FontCache draw2d.FontCache
+ glyphCache draw2dbase.GlyphCache
glyphBuf *truetype.GlyphBuf
- DPI int
+ DPI int
}
// NewGraphicContext creates a new Graphic context from an image.
@@ -136,6 +137,8 @@ func NewGraphicContext(width, height int) *GraphicContext {
NewPainter(),
raster.NewRasterizer(width, height),
raster.NewRasterizer(width, height),
+ draw2d.GetGlobalFontCache(),
+ draw2dbase.NewGlyphCache(),
&truetype.GlyphBuf{},
92,
}
@@ -143,16 +146,15 @@ func NewGraphicContext(width, height int) *GraphicContext {
}
func (gc *GraphicContext) loadCurrentFont() (*truetype.Font, error) {
- font := draw2d.GetFont(gc.Current.FontData)
- if font == nil {
- font = draw2d.GetFont(draw2dbase.DefaultFontData)
+ font, err := gc.FontCache.Load(gc.Current.FontData)
+ if err != nil {
+ font, err = gc.FontCache.Load(draw2dbase.DefaultFontData)
}
- if font == nil {
- return nil, errors.New("No font set, and no default font available.")
+ if font != nil {
+ gc.SetFont(font)
+ gc.SetFontSize(gc.Current.FontSize)
}
- gc.SetFont(font)
- gc.SetFontSize(gc.Current.FontSize)
- return font, nil
+ return font, err
}
func (gc *GraphicContext) drawGlyph(glyph truetype.Index, dx, dy float64) error {
@@ -217,7 +219,7 @@ func (gc *GraphicContext) FillStringAt(text string, x, y float64) (width float64
if hasPrev {
x += fUnitsToFloat64(f.Kern(fixed.Int26_6(gc.Current.Scale), prev, index))
}
- glyph := draw2dbase.FetchGlyph(gc, fontName, r)
+ glyph := gc.glyphCache.Fetch(gc, fontName, r)
x += glyph.Fill(gc, x, y)
prev, hasPrev = index, true
}
@@ -283,7 +285,7 @@ func (gc *GraphicContext) StrokeStringAt(text string, x, y float64) (width float
if hasPrev {
x += fUnitsToFloat64(f.Kern(fixed.Int26_6(gc.Current.Scale), prev, index))
}
- glyph := draw2dbase.FetchGlyph(gc, fontName, r)
+ glyph := gc.glyphCache.Fetch(gc, fontName, r)
x += glyph.Stroke(gc, x, y)
prev, hasPrev = index, true
}
diff --git a/vendor/github.com/llgcode/draw2d/draw2dimg/curve_limit_test.go b/vendor/github.com/llgcode/draw2d/draw2dimg/curve_limit_test.go
new file mode 100644
index 0000000..26ecdb0
--- /dev/null
+++ b/vendor/github.com/llgcode/draw2d/draw2dimg/curve_limit_test.go
@@ -0,0 +1,189 @@
+package draw2dimg
+
+import (
+ "fmt"
+ "github.com/golang/freetype/truetype"
+ "github.com/llgcode/draw2d"
+ "github.com/llgcode/draw2d/draw2dkit"
+ "golang.org/x/image/font/gofont/goregular"
+ "image"
+ "image/color"
+ "testing"
+)
+
+// font generated from icomoon.io and converted to go byte slice
+// contains only two glyphs
+// \u2716 - which should look like a cross
+// \u25cb - which should look like an empty circle
+var icoTTF = []byte{
+ 0, 1, 0, 0, 0, 12, 0, 128, 0, 3, 0, 64, 71, 83, 85, 66, 219, 7, 221, 185,
+ 0, 0, 0, 204, 0, 0, 0, 188, 79, 83, 47, 50, 175, 17, 51, 150, 0, 0, 1, 136,
+ 0, 0, 0, 96, 99, 109, 97, 112, 37, 204, 43, 67, 0, 0, 1, 232, 0, 0, 0, 148,
+ 103, 97, 115, 112, 0, 0, 0, 16, 0, 0, 2, 124, 0, 0, 0, 8, 103, 108, 121, 102,
+ 163, 112, 233, 32, 0, 0, 2, 132, 0, 0, 3, 64, 104, 101, 97, 100, 15, 49, 194, 135,
+ 0, 0, 5, 196, 0, 0, 0, 54, 104, 104, 101, 97, 7, 194, 3, 217, 0, 0, 5, 252,
+ 0, 0, 0, 36, 104, 109, 116, 120, 14, 0, 0, 2, 0, 0, 6, 32, 0, 0, 0, 96,
+ 108, 111, 99, 97, 6, 168, 5, 226, 0, 0, 6, 128, 0, 0, 0, 50, 109, 97, 120, 112,
+ 0, 27, 0, 86, 0, 0, 6, 180, 0, 0, 0, 32, 110, 97, 109, 101, 108, 36, 213, 69,
+ 0, 0, 6, 212, 0, 0, 1, 170, 112, 111, 115, 116, 0, 3, 0, 0, 0, 0, 8, 128,
+ 0, 0, 0, 32, 0, 1, 0, 0, 0, 10, 0, 30, 0, 44, 0, 1, 108, 97, 116, 110,
+ 0, 8, 0, 4, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 108, 105, 103, 97,
+ 0, 8, 0, 0, 0, 1, 0, 0, 0, 1, 0, 4, 0, 4, 0, 0, 0, 1, 0, 10,
+ 0, 0, 0, 1, 0, 12, 0, 3, 0, 22, 0, 54, 0, 120, 0, 1, 0, 3, 0, 8,
+ 0, 17, 0, 23, 0, 2, 0, 6, 0, 18, 0, 22, 0, 5, 0, 17, 0, 16, 0, 18,
+ 0, 18, 0, 22, 0, 6, 0, 6, 0, 15, 0, 8, 0, 10, 0, 14, 0, 2, 0, 6,
+ 0, 38, 0, 21, 0, 15, 0, 6, 0, 9, 0, 12, 0, 16, 0, 4, 0, 20, 0, 15,
+ 0, 8, 0, 11, 0, 10, 0, 8, 0, 13, 0, 10, 0, 9, 0, 21, 0, 13, 0, 6,
+ 0, 9, 0, 12, 0, 16, 0, 4, 0, 7, 0, 20, 0, 19, 0, 19, 0, 16, 0, 15,
+ 0, 5, 0, 1, 0, 4, 0, 22, 0, 2, 0, 23, 0, 3, 3, 85, 1, 144, 0, 5,
+ 0, 0, 2, 153, 2, 204, 0, 0, 0, 143, 2, 153, 2, 204, 0, 0, 1, 235, 0, 51,
+ 1, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0,
+ 160, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 64, 0, 0, 39, 23,
+ 3, 192, 255, 192, 0, 64, 3, 192, 0, 64, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 32, 0, 0, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 28,
+ 0, 1, 0, 3, 0, 0, 0, 28, 0, 3, 0, 1, 0, 0, 0, 28, 0, 4, 0, 120,
+ 0, 0, 0, 26, 0, 16, 0, 3, 0, 10, 0, 1, 0, 32, 0, 45, 0, 51, 0, 101,
+ 0, 105, 0, 108, 0, 111, 0, 117, 37, 203, 39, 23, 255, 253, 255, 255, 0, 0, 0, 0,
+ 0, 32, 0, 45, 0, 51, 0, 97, 0, 104, 0, 107, 0, 110, 0, 114, 37, 203, 39, 22,
+ 255, 253, 255, 255, 0, 1, 255, 227, 255, 215, 255, 210, 255, 165, 255, 163, 255, 162, 255, 161,
+ 255, 159, 218, 74, 217, 0, 0, 3, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1,
+ 255, 255, 0, 15, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 55, 57,
+ 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 55, 57,
+ 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 55, 57,
+ 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 55, 57,
+ 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 55, 57,
+ 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 55, 57,
+ 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 55, 57,
+ 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 55, 57,
+ 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 55, 57,
+ 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 55, 57,
+ 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 55, 57,
+ 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 55, 57,
+ 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 55, 57,
+ 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 55, 57,
+ 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 55, 57,
+ 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 55, 57,
+ 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 55, 57,
+ 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 55, 57,
+ 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 55, 57,
+ 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 55, 57,
+ 1, 0, 0, 0, 0, 2, 0, 0, 255, 192, 4, 0, 3, 192, 0, 27, 0, 55, 0, 0,
+ 1, 34, 7, 14, 1, 7, 6, 21, 20, 23, 30, 1, 23, 22, 51, 50, 55, 62, 1, 55,
+ 54, 53, 52, 39, 46, 1, 39, 38, 3, 34, 39, 46, 1, 39, 38, 53, 52, 55, 62, 1,
+ 55, 54, 51, 50, 23, 30, 1, 23, 22, 21, 20, 7, 14, 1, 7, 6, 2, 0, 106, 93,
+ 94, 139, 40, 40, 40, 40, 139, 94, 93, 106, 106, 93, 94, 139, 40, 40, 40, 40, 139, 94,
+ 93, 106, 80, 69, 70, 105, 30, 30, 30, 30, 105, 70, 69, 80, 80, 69, 70, 105, 30, 30,
+ 30, 30, 105, 70, 69, 3, 192, 40, 40, 139, 94, 93, 106, 106, 93, 94, 139, 40, 40, 40,
+ 40, 139, 94, 93, 106, 106, 93, 94, 139, 40, 40, 252, 128, 30, 30, 105, 70, 69, 80, 80,
+ 69, 70, 105, 30, 30, 30, 30, 105, 70, 69, 80, 80, 69, 70, 105, 30, 30, 0, 0, 0,
+ 0, 1, 0, 2, 255, 194, 3, 254, 3, 190, 0, 83, 0, 0, 37, 56, 1, 49, 9, 1,
+ 56, 1, 49, 62, 1, 55, 54, 38, 47, 1, 46, 1, 7, 14, 1, 7, 56, 1, 49, 9,
+ 1, 56, 1, 49, 46, 1, 39, 38, 6, 15, 1, 14, 1, 23, 30, 1, 23, 56, 1, 49,
+ 9, 1, 56, 1, 49, 14, 1, 7, 6, 22, 31, 1, 30, 1, 55, 62, 1, 55, 56, 1,
+ 49, 9, 1, 56, 1, 49, 30, 1, 23, 22, 54, 63, 1, 62, 1, 39, 46, 1, 3, 247,
+ 254, 201, 1, 55, 2, 4, 1, 3, 3, 7, 147, 7, 18, 9, 3, 6, 2, 254, 201, 254,
+ 201, 2, 6, 3, 9, 18, 7, 147, 7, 3, 3, 1, 4, 2, 1, 55, 254, 201, 2, 4,
+ 1, 3, 3, 7, 147, 7, 18, 9, 3, 6, 2, 1, 55, 1, 55, 2, 6, 3, 9, 18,
+ 7, 147, 7, 3, 3, 1, 4, 137, 1, 55, 1, 55, 2, 6, 3, 9, 18, 7, 147, 7,
+ 3, 3, 1, 4, 2, 254, 201, 1, 55, 2, 4, 1, 3, 3, 7, 147, 7, 18, 9, 3,
+ 6, 2, 254, 201, 254, 201, 2, 6, 3, 9, 18, 7, 147, 7, 3, 3, 1, 4, 2, 1,
+ 55, 254, 201, 2, 4, 1, 3, 3, 7, 147, 7, 18, 9, 3, 6, 0, 0, 1, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 55, 57, 1, 0, 0, 0, 0, 1, 0, 0,
+ 0, 1, 0, 0, 32, 120, 21, 165, 95, 15, 60, 245, 0, 11, 4, 0, 0, 0, 0, 0,
+ 214, 9, 63, 5, 0, 0, 0, 0, 214, 9, 63, 5, 0, 0, 255, 192, 4, 0, 3, 192,
+ 0, 0, 0, 8, 0, 2, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 3, 192, 255, 192,
+ 0, 0, 4, 0, 0, 0, 0, 0, 4, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 24, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 2,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 20, 0, 30, 0, 40, 0, 50, 0, 60,
+ 0, 70, 0, 80, 0, 90, 0, 100, 0, 110, 0, 120, 0, 130, 0, 140, 0, 150, 0, 160,
+ 0, 170, 0, 180, 0, 190, 0, 200, 1, 32, 1, 150, 1, 160, 0, 0, 0, 1, 0, 0,
+ 0, 24, 0, 84, 0, 2, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 14, 0, 174, 0, 1, 0, 0, 0, 0,
+ 0, 1, 0, 10, 0, 0, 0, 1, 0, 0, 0, 0, 0, 2, 0, 7, 0, 123, 0, 1,
+ 0, 0, 0, 0, 0, 3, 0, 10, 0, 63, 0, 1, 0, 0, 0, 0, 0, 4, 0, 10,
+ 0, 144, 0, 1, 0, 0, 0, 0, 0, 5, 0, 11, 0, 30, 0, 1, 0, 0, 0, 0,
+ 0, 6, 0, 10, 0, 93, 0, 1, 0, 0, 0, 0, 0, 10, 0, 26, 0, 174, 0, 3,
+ 0, 1, 4, 9, 0, 1, 0, 20, 0, 10, 0, 3, 0, 1, 4, 9, 0, 2, 0, 14,
+ 0, 130, 0, 3, 0, 1, 4, 9, 0, 3, 0, 20, 0, 73, 0, 3, 0, 1, 4, 9,
+ 0, 4, 0, 20, 0, 154, 0, 3, 0, 1, 4, 9, 0, 5, 0, 22, 0, 41, 0, 3,
+ 0, 1, 4, 9, 0, 6, 0, 20, 0, 103, 0, 3, 0, 1, 4, 9, 0, 10, 0, 52,
+ 0, 200, 105, 99, 111, 45, 112, 101, 110, 101, 103, 111, 0, 105, 0, 99, 0, 111, 0, 45,
+ 0, 112, 0, 101, 0, 110, 0, 101, 0, 103, 0, 111, 86, 101, 114, 115, 105, 111, 110, 32,
+ 49, 46, 48, 0, 86, 0, 101, 0, 114, 0, 115, 0, 105, 0, 111, 0, 110, 0, 32, 0,
+ 49, 0, 46, 0, 48, 105, 99, 111, 45, 112, 101, 110, 101, 103, 111, 0, 105, 0, 99, 0,
+ 111, 0, 45, 0, 112, 0, 101, 0, 110, 0, 101, 0, 103, 0, 111, 105, 99, 111, 45, 112,
+ 101, 110, 101, 103, 111, 0, 105, 0, 99, 0, 111, 0, 45, 0, 112, 0, 101, 0, 110, 0,
+ 101, 0, 103, 0, 111, 82, 101, 103, 117, 108, 97, 114, 0, 82, 0, 101, 0, 103, 0, 117,
+ 0, 108, 0, 97, 0, 114, 105, 99, 111, 45, 112, 101, 110, 101, 103, 111, 0, 105, 0, 99,
+ 0, 111, 0, 45, 0, 112, 0, 101, 0, 110, 0, 101, 0, 103, 0, 111, 70, 111, 110, 116,
+ 32, 103, 101, 110, 101, 114, 97, 116, 101, 100, 32, 98, 121, 32, 73, 99, 111, 77, 111, 111,
+ 110, 46, 0, 70, 0, 111, 0, 110, 0, 116, 0, 32, 0, 103, 0, 101, 0, 110, 0, 101,
+ 0, 114, 0, 97, 0, 116, 0, 101, 0, 100, 0, 32, 0, 98, 0, 121, 0, 32, 0, 73,
+ 0, 99, 0, 111, 0, 77, 0, 111, 0, 111, 0, 110, 0, 46, 0, 0, 0, 3, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+}
+
+type customFontCache map[string]*truetype.Font
+
+func (fc customFontCache) Store(fd draw2d.FontData, font *truetype.Font) {
+ fc[fd.Name] = font
+}
+
+func (fc customFontCache) Load(fd draw2d.FontData) (*truetype.Font, error) {
+ font, stored := fc[fd.Name]
+ if !stored {
+ return nil, fmt.Errorf("font %s is not stored in font cache", fd.Name)
+ }
+ return font, nil
+}
+
+func initFontCache() { // init font cache
+ fontCache := customFontCache{}
+ // add gofont to cache
+ gofont, err := truetype.Parse(goregular.TTF)
+ if err != nil {
+ panic(err)
+ }
+ fontCache.Store(draw2d.FontData{Name: "goregular"}, gofont)
+ // add icofont to cache
+ icofont, err := truetype.Parse(icoTTF)
+ if err != nil {
+ panic(err)
+ }
+ fontCache.Store(draw2d.FontData{Name: "ico"}, icofont)
+
+ draw2d.SetFontCache(fontCache)
+}
+
+func TestCurveIndexOutOfRange(t *testing.T) {
+
+ initFontCache()
+
+ // Initialize the graphic context on an RGBA image
+ dest := image.NewRGBA(image.Rect(0, 0, 512, 512))
+ gc := NewGraphicContext(dest)
+
+ // background
+ gc.SetFillColor(color.RGBA{0xef, 0xef, 0xef, 0xff})
+ draw2dkit.Rectangle(gc, 0, 0, 512, 512)
+ gc.Fill()
+
+ // text
+ gc.SetFontSize(20)
+ gc.SetFillColor(color.RGBA{0x10, 0x10, 0x10, 0xff})
+ gc.SetFontData(draw2d.FontData{Name: "goregular"})
+
+ // gc.FillStringAt("Hello", 128, 120) // this works well
+
+ gc.SetFontData(draw2d.FontData{Name: "ico"})
+ gc.FillStringAt("\u25cb", 128, 150) // this also works
+ gc.FillStringAt("\u2716", 128, 170) // Works now
+
+ SaveToPngFile("_test_hello.png", dest)
+}
diff --git a/vendor/github.com/llgcode/draw2d/draw2dimg/ftgc.go b/vendor/github.com/llgcode/draw2d/draw2dimg/ftgc.go
index abaf7e5..c07e1da 100644
--- a/vendor/github.com/llgcode/draw2d/draw2dimg/ftgc.go
+++ b/vendor/github.com/llgcode/draw2d/draw2dimg/ftgc.go
@@ -4,7 +4,6 @@
package draw2dimg
import (
- "errors"
"image"
"image/color"
"log"
@@ -35,6 +34,8 @@ type GraphicContext struct {
painter Painter
fillRasterizer *raster.Rasterizer
strokeRasterizer *raster.Rasterizer
+ FontCache draw2d.FontCache
+ glyphCache draw2dbase.GlyphCache
glyphBuf *truetype.GlyphBuf
DPI int
}
@@ -74,6 +75,8 @@ func NewGraphicContextWithPainter(img draw.Image, painter Painter) *GraphicConte
painter,
raster.NewRasterizer(width, height),
raster.NewRasterizer(width, height),
+ draw2d.GetGlobalFontCache(),
+ draw2dbase.NewGlyphCache(),
&truetype.GlyphBuf{},
dpi,
}
@@ -136,7 +139,7 @@ func (gc *GraphicContext) FillStringAt(text string, x, y float64) (width float64
if hasPrev {
x += fUnitsToFloat64(f.Kern(fixed.Int26_6(gc.Current.Scale), prev, index))
}
- glyph := draw2dbase.FetchGlyph(gc, fontName, r)
+ glyph := gc.glyphCache.Fetch(gc, fontName, r)
x += glyph.Fill(gc, x, y)
prev, hasPrev = index, true
}
@@ -163,7 +166,7 @@ func (gc *GraphicContext) StrokeStringAt(text string, x, y float64) (width float
if hasPrev {
x += fUnitsToFloat64(f.Kern(fixed.Int26_6(gc.Current.Scale), prev, index))
}
- glyph := draw2dbase.FetchGlyph(gc, fontName, r)
+ glyph := gc.glyphCache.Fetch(gc, fontName, r)
x += glyph.Stroke(gc, x, y)
prev, hasPrev = index, true
}
@@ -171,16 +174,15 @@ func (gc *GraphicContext) StrokeStringAt(text string, x, y float64) (width float
}
func (gc *GraphicContext) loadCurrentFont() (*truetype.Font, error) {
- font := draw2d.GetFont(gc.Current.FontData)
- if font == nil {
- font = draw2d.GetFont(draw2dbase.DefaultFontData)
+ font, err := gc.FontCache.Load(gc.Current.FontData)
+ if err != nil {
+ font, err = gc.FontCache.Load(draw2dbase.DefaultFontData)
}
- if font == nil {
- return nil, errors.New("No font set, and no default font available.")
+ if font != nil {
+ gc.SetFont(font)
+ gc.SetFontSize(gc.Current.FontSize)
}
- gc.SetFont(font)
- gc.SetFontSize(gc.Current.FontSize)
- return font, nil
+ return font, err
}
// p is a truetype.Point measured in FUnits and positive Y going upwards.
diff --git a/vendor/github.com/llgcode/draw2d/font.go b/vendor/github.com/llgcode/draw2d/font.go
index cd0ec1b..90ef9a1 100644
--- a/vendor/github.com/llgcode/draw2d/font.go
+++ b/vendor/github.com/llgcode/draw2d/font.go
@@ -8,6 +8,7 @@ import (
"log"
"path/filepath"
+ "sync"
"github.com/golang/freetype/truetype"
)
@@ -80,11 +81,15 @@ func GetFontFolder() string {
}
func SetFontFolder(folder string) {
- defaultFonts.folder = filepath.Clean(folder)
+ defaultFonts.setFolder(filepath.Clean(folder))
+}
+
+func GetGlobalFontCache() FontCache {
+ return fontCache
}
func SetFontNamer(fn FontFileNamer) {
- defaultFonts.namer = fn
+ defaultFonts.setNamer(fn)
}
// Types implementing this interface can be passed to SetFontCache to change the
@@ -113,13 +118,24 @@ func SetFontCache(cache FontCache) {
}
}
-type defaultFontCache struct {
+// FolderFontCache can Load font from folder
+type FolderFontCache struct {
fonts map[string]*truetype.Font
folder string
namer FontFileNamer
}
-func (cache *defaultFontCache) Load(fontData FontData) (font *truetype.Font, err error) {
+// NewFolderFontCache creates FolderFontCache
+func NewFolderFontCache(folder string) *FolderFontCache {
+ return &FolderFontCache{
+ fonts: make(map[string]*truetype.Font),
+ folder: folder,
+ namer: FontFileName,
+ }
+}
+
+// Load a font from cache if exists otherwise it will load the font from file
+func (cache *FolderFontCache) Load(fontData FontData) (font *truetype.Font, err error) {
if font = cache.fonts[cache.namer(fontData)]; font != nil {
return font, nil
}
@@ -139,16 +155,77 @@ func (cache *defaultFontCache) Load(fontData FontData) (font *truetype.Font, err
return
}
-func (cache *defaultFontCache) Store(fontData FontData, font *truetype.Font) {
+// Store a font to this cache
+func (cache *FolderFontCache) Store(fontData FontData, font *truetype.Font) {
cache.fonts[cache.namer(fontData)] = font
}
-var (
- defaultFonts = &defaultFontCache{
+// SyncFolderFontCache can Load font from folder
+type SyncFolderFontCache struct {
+ sync.RWMutex
+ fonts map[string]*truetype.Font
+ folder string
+ namer FontFileNamer
+}
+
+
+
+// NewSyncFolderFontCache creates SyncFolderFontCache
+func NewSyncFolderFontCache(folder string) *SyncFolderFontCache {
+ return &SyncFolderFontCache{
fonts: make(map[string]*truetype.Font),
- folder: "../resource/font",
+ folder: folder,
namer: FontFileName,
}
+}
+
+func (cache *SyncFolderFontCache) setFolder(folder string) {
+ cache.Lock()
+ cache.folder = folder
+ cache.Unlock()
+}
+
+func (cache *SyncFolderFontCache) setNamer(namer FontFileNamer) {
+ cache.Lock()
+ cache.namer = namer
+ cache.Unlock()
+}
+
+// Load a font from cache if exists otherwise it will load the font from file
+func (cache *SyncFolderFontCache) Load(fontData FontData) (font *truetype.Font, err error) {
+ cache.RLock()
+ font = cache.fonts[cache.namer(fontData)]
+ cache.RUnlock()
+
+ if font != nil {
+ return font, nil
+ }
+
+ var data []byte
+ var file = cache.namer(fontData)
+
+ if data, err = ioutil.ReadFile(filepath.Join(cache.folder, file)); err != nil {
+ return
+ }
+
+ if font, err = truetype.Parse(data); err != nil {
+ return
+ }
+ cache.Lock()
+ cache.fonts[file] = font
+ cache.Unlock()
+ return
+}
+
+// Store a font to this cache
+func (cache *SyncFolderFontCache) Store(fontData FontData, font *truetype.Font) {
+ cache.Lock()
+ cache.fonts[cache.namer(fontData)] = font
+ cache.Unlock()
+}
+
+var (
+ defaultFonts = NewSyncFolderFontCache("../resource/font")
fontCache FontCache = defaultFonts
)
diff --git a/vendor/github.com/llgcode/draw2d/output/samples/geometry.png b/vendor/github.com/llgcode/draw2d/output/samples/geometry.png
index a2c966e..b68bb32 100644
--- a/vendor/github.com/llgcode/draw2d/output/samples/geometry.png
+++ b/vendor/github.com/llgcode/draw2d/output/samples/geometry.png
Binary files differ
diff --git a/vendor/github.com/llgcode/draw2d/output/samples/postscript.png b/vendor/github.com/llgcode/draw2d/output/samples/postscript.png
index 53e1a63..05e1107 100644
--- a/vendor/github.com/llgcode/draw2d/output/samples/postscript.png
+++ b/vendor/github.com/llgcode/draw2d/output/samples/postscript.png
Binary files differ
diff --git a/vendor/github.com/llgcode/draw2d/sync_test.go b/vendor/github.com/llgcode/draw2d/sync_test.go
new file mode 100644
index 0000000..6c5afd8
--- /dev/null
+++ b/vendor/github.com/llgcode/draw2d/sync_test.go
@@ -0,0 +1,46 @@
+// go test -race -test.v sync_test.go
+
+package draw2d_test
+
+
+import (
+ "fmt"
+ "github.com/llgcode/draw2d"
+ "github.com/llgcode/draw2d/draw2dimg"
+ "github.com/llgcode/draw2d/draw2dkit"
+ "image"
+ "testing"
+)
+
+func TestSync(t *testing.T) {
+ ch := make(chan int)
+ limit := 2
+ for i := 0; i < limit; i++ {
+ go Draw(i, ch)
+ }
+
+ for i := 0; i < limit; i++ {
+ counter := <-ch
+ t.Logf("Goroutine %d returned\n", counter)
+ }
+}
+
+func Draw(i int, ch chan<- int) {
+ draw2d.SetFontFolder("./resource/font")
+ // Draw a rounded rectangle using default colors
+ dest := image.NewRGBA(image.Rect(0, 0, 297, 210.0))
+ gc := draw2dimg.NewGraphicContext(dest)
+
+ draw2dkit.RoundedRectangle(gc, 5, 5, 135, 95, 10, 10)
+ gc.FillStroke()
+
+ // Set the fill text color to black
+ gc.SetFillColor(image.Black)
+ gc.SetFontSize(14)
+
+ // Display Hello World dimensions
+ x1, y1, x2, y2 := gc.GetStringBounds("Hello world")
+ gc.FillStringAt(fmt.Sprintf("%.2f %.2f %.2f %.2f", x1, y1, x2, y2), 0, 0)
+
+ ch <- i
+}
diff --git a/vendor/golang.org/x/image/README b/vendor/golang.org/x/image/README
deleted file mode 100644
index 4620380..0000000
--- a/vendor/golang.org/x/image/README
+++ /dev/null
@@ -1,3 +0,0 @@
-This repository holds supplementary Go image libraries.
-
-To submit changes to this repository, see http://golang.org/doc/contribute.html.
diff --git a/vendor/golang.org/x/image/README.md b/vendor/golang.org/x/image/README.md
new file mode 100644
index 0000000..0a312b4
--- /dev/null
+++ b/vendor/golang.org/x/image/README.md
@@ -0,0 +1,17 @@
+# Go Images
+
+This repository holds supplementary Go image libraries.
+
+## Download/Install
+
+The easiest way to install is to run `go get -u golang.org/x/image`. You can
+also manually git clone the repository to `$GOPATH/src/golang.org/x/image`.
+
+## Report Issues / Send Patches
+
+This repository uses Gerrit for code changes. To learn how to submit changes to
+this repository, see https://golang.org/doc/contribute.html.
+
+The main issue tracker for the image repository is located at
+https://github.com/golang/go/issues. Prefix your issue with "x/image:" in the
+subject line, so it is easy to find.
diff --git a/vendor/golang.org/x/image/draw/gen.go b/vendor/golang.org/x/image/draw/gen.go
index 65a7123..822bb6a 100644
--- a/vendor/golang.org/x/image/draw/gen.go
+++ b/vendor/golang.org/x/image/draw/gen.go
@@ -877,8 +877,9 @@ func relName(s string) string {
const (
codeRoot = `
func (z $receiver) Scale(dst Image, dr image.Rectangle, src image.Image, sr image.Rectangle, op Op, opts *Options) {
- // Try to simplify a Scale to a Copy.
- if dr.Size() == sr.Size() {
+ // Try to simplify a Scale to a Copy when DstMask is not specified.
+ // If DstMask is not nil, Copy will call Scale back with same dr and sr, and cause stack overflow.
+ if dr.Size() == sr.Size() && (opts == nil || opts.DstMask == nil) {
Copy(dst, dr.Min, src, sr, op, opts)
return
}
diff --git a/vendor/golang.org/x/image/draw/impl.go b/vendor/golang.org/x/image/draw/impl.go
index 637887b..75498ad 100644
--- a/vendor/golang.org/x/image/draw/impl.go
+++ b/vendor/golang.org/x/image/draw/impl.go
@@ -11,8 +11,9 @@ import (
)
func (z nnInterpolator) Scale(dst Image, dr image.Rectangle, src image.Image, sr image.Rectangle, op Op, opts *Options) {
- // Try to simplify a Scale to a Copy.
- if dr.Size() == sr.Size() {
+ // Try to simplify a Scale to a Copy when DstMask is not specified.
+ // If DstMask is not nil, Copy will call Scale back with same dr and sr, and cause stack overflow.
+ if dr.Size() == sr.Size() && (opts == nil || opts.DstMask == nil) {
Copy(dst, dr.Min, src, sr, op, opts)
return
}
@@ -1048,8 +1049,9 @@ func (nnInterpolator) transform_Image_Image_Src(dst Image, dr, adr image.Rectang
}
func (z ablInterpolator) Scale(dst Image, dr image.Rectangle, src image.Image, sr image.Rectangle, op Op, opts *Options) {
- // Try to simplify a Scale to a Copy.
- if dr.Size() == sr.Size() {
+ // Try to simplify a Scale to a Copy when DstMask is not specified.
+ // If DstMask is not nil, Copy will call Scale back with same dr and sr, and cause stack overflow.
+ if dr.Size() == sr.Size() && (opts == nil || opts.DstMask == nil) {
Copy(dst, dr.Min, src, sr, op, opts)
return
}
diff --git a/vendor/golang.org/x/image/draw/scale_test.go b/vendor/golang.org/x/image/draw/scale_test.go
index 5e184c2..ea41940 100644
--- a/vendor/golang.org/x/image/draw/scale_test.go
+++ b/vendor/golang.org/x/image/draw/scale_test.go
@@ -551,6 +551,17 @@ func TestRectDstMask(t *testing.T) {
}
}
+func TestDstMaskSameSizeCopy(t *testing.T) {
+ bounds := image.Rect(0, 0, 42, 42)
+ src := image.Opaque
+ dst := image.NewRGBA(bounds)
+ mask := image.NewRGBA(bounds)
+
+ Copy(dst, image.ZP, src, bounds, Src, &Options{
+ DstMask: mask,
+ })
+}
+
// TODO: delete this wrapper type once Go 1.5 is released, where an
// image.Rectangle implements image.Image.
type rectImage image.Rectangle
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