зеркало из https://github.com/golang/build.git
internal/task: switch to opentype for TTF font rendering
When working on CL 358897, I forgot that there's already an SFNT font parser and glyph rasterizer available in the x/image module. Using it produces an equivalent final image, and allows x/build to depend on 1 less module. Also add a regression test for drawTerminal. Updates golang/go#47403. Change-Id: I77166a2180a7db9c81a30f77b12bb20dcd21bd8b Reviewed-on: https://go-review.googlesource.com/c/build/+/388834 Trust: Dmitri Shuralyov <dmitshur@golang.org> Run-TryBot: Dmitri Shuralyov <dmitshur@golang.org> TryBot-Result: Gopher Robot <gobot@golang.org> Reviewed-by: Heschi Kreinick <heschi@google.com>
This commit is contained in:
Родитель
1c23949106
Коммит
00ab59d78d
1
go.mod
1
go.mod
|
@ -19,7 +19,6 @@ require (
|
|||
github.com/esimov/stackblur-go v1.0.1
|
||||
github.com/gliderlabs/ssh v0.3.3
|
||||
github.com/golang-migrate/migrate/v4 v4.15.0-beta.3
|
||||
github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0
|
||||
github.com/golang/protobuf v1.5.2
|
||||
github.com/google/go-cmp v0.5.6
|
||||
github.com/google/go-github v17.0.0+incompatible
|
||||
|
|
2
go.sum
2
go.sum
|
@ -272,8 +272,6 @@ github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69
|
|||
github.com/golang-migrate/migrate/v4 v4.15.0-beta.3 h1:tqLMcxs6gB6+b2Jhwao4s2sNMSKku+0rjtBtKucKWkg=
|
||||
github.com/golang-migrate/migrate/v4 v4.15.0-beta.3/go.mod h1:g9qbiDvB47WyrRnNu2t2gMZFNHKnatsYRxsGZbCi4EM=
|
||||
github.com/golang-sql/civil v0.0.0-20190719163853-cb61b32ac6fe/go.mod h1:8vg3r2VgvsThLBIFL93Qb5yWzgyZWhEmBwUJWevAkK0=
|
||||
github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0 h1:DACJavvAHhabrF08vX0COfcOBJRhZ8lUbR+ZWIs0Y5g=
|
||||
github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0/go.mod h1:E/TSTwGwJL78qG/PmXZO1EjYhfJinVAhrmmHX6Z8B9k=
|
||||
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
|
||||
github.com/golang/groupcache v0.0.0-20160516000752-02826c3e7903/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
|
||||
github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
|
||||
|
|
Двоичный файл не отображается.
После Ширина: | Высота: | Размер: 107 KiB |
|
@ -25,11 +25,11 @@ import (
|
|||
|
||||
"github.com/dghubble/oauth1"
|
||||
"github.com/esimov/stackblur-go"
|
||||
"github.com/golang/freetype/truetype"
|
||||
"golang.org/x/build/internal/secret"
|
||||
"golang.org/x/build/internal/workflow"
|
||||
"golang.org/x/image/font"
|
||||
"golang.org/x/image/font/gofont/gomono"
|
||||
"golang.org/x/image/font/opentype"
|
||||
"golang.org/x/image/math/fixed"
|
||||
)
|
||||
|
||||
|
@ -496,7 +496,7 @@ func (f golangorgDLFile) GOARCH() string {
|
|||
// with the given text displayed.
|
||||
func drawTerminal(text string) (image.Image, error) {
|
||||
// Load font from TTF data.
|
||||
f, err := truetype.Parse(gomono.TTF)
|
||||
f, err := opentype.Parse(gomono.TTF)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -521,7 +521,11 @@ func drawTerminal(text string) (image.Image, error) {
|
|||
roundedRect(image.Rect(50, 80, width-50, height-80), 10), image.Point{}, draw.Over)
|
||||
|
||||
// Text.
|
||||
d := font.Drawer{Dst: m, Src: image.White, Face: truetype.NewFace(f, &truetype.Options{Size: 24})}
|
||||
face, err := opentype.NewFace(f, &opentype.FaceOptions{Size: 24, DPI: 72})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
d := font.Drawer{Dst: m, Src: image.White, Face: face}
|
||||
const lineHeight = 32
|
||||
for n, line := range strings.Split(text, "\n") {
|
||||
d.Dot = fixed.P(80, 135+n*lineHeight)
|
||||
|
|
|
@ -7,10 +7,15 @@ package task
|
|||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"flag"
|
||||
"fmt"
|
||||
"image"
|
||||
"image/png"
|
||||
"io"
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"testing"
|
||||
|
||||
"golang.org/x/build/internal/workflow"
|
||||
|
@ -175,6 +180,79 @@ func (f fmtWriter) Printf(format string, v ...interface{}) {
|
|||
fmt.Fprintf(f.w, format, v...)
|
||||
}
|
||||
|
||||
var updateFlag = flag.Bool("update", false, "Update golden files.")
|
||||
|
||||
func TestDrawTerminal(t *testing.T) {
|
||||
got, err := drawTerminal(`$ go install golang.org/dl/go1.18beta1@latest
|
||||
$ go1.18beta1 download
|
||||
Downloaded 0.0% ( 0 / 111109966 bytes) ...
|
||||
Downloaded 50.0% ( 55554983 / 111109966 bytes) ...
|
||||
Downloaded 100.0% (111109966 / 111109966 bytes)
|
||||
Unpacking go1.18beta1.linux-s390x.tar.gz ...
|
||||
Success. You may now run 'go1.18beta1'
|
||||
$ go1.18beta1 version
|
||||
go version go1.18beta1 linux/s390x`)
|
||||
if err != nil {
|
||||
t.Fatalf("drawTerminal: got error=%v, want nil", err)
|
||||
}
|
||||
if *updateFlag {
|
||||
encodePNG(t, filepath.Join("testdata", "terminal.png"), got)
|
||||
return
|
||||
}
|
||||
want := decodePNG(t, filepath.Join("testdata", "terminal.png"))
|
||||
if !got.Bounds().Eq(want.Bounds()) {
|
||||
t.Fatalf("drawTerminal: got image bounds=%v, want %v", got.Bounds(), want.Bounds())
|
||||
}
|
||||
diff := func(a, b uint32) uint64 {
|
||||
if a < b {
|
||||
return uint64(b - a)
|
||||
}
|
||||
return uint64(a - b)
|
||||
}
|
||||
var total uint64
|
||||
for y := 0; y < want.Bounds().Dy(); y++ {
|
||||
for x := 0; x < want.Bounds().Dx(); x++ {
|
||||
r0, g0, b0, a0 := got.At(x, y).RGBA()
|
||||
r1, g1, b1, a1 := want.At(x, y).RGBA()
|
||||
const D = 0xffff * 20 / 100 // Diff threshold of 20% for RGB color components.
|
||||
if diff(r0, r1) > D || diff(g0, g1) > D || diff(b0, b1) > D || a0 != a1 {
|
||||
t.Errorf("at (%d, %d):\n got RGBA %v\nwant RGBA %v", x, y, got.At(x, y), want.At(x, y))
|
||||
}
|
||||
total += diff(r0, r1) + diff(g0, g1) + diff(b0, b1)
|
||||
}
|
||||
}
|
||||
if testing.Verbose() {
|
||||
t.Logf("average pixel color diff: %v%%", 100*float64(total)/float64(0xffff*want.Bounds().Dx()*want.Bounds().Dy()))
|
||||
}
|
||||
}
|
||||
|
||||
func encodePNG(t *testing.T, name string, m image.Image) {
|
||||
t.Helper()
|
||||
var buf bytes.Buffer
|
||||
err := (&png.Encoder{CompressionLevel: png.BestCompression}).Encode(&buf, m)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
err = os.WriteFile(name, buf.Bytes(), 0644)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
||||
func decodePNG(t *testing.T, name string) image.Image {
|
||||
t.Helper()
|
||||
f, err := os.Open(name)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
defer f.Close()
|
||||
m, err := png.Decode(f)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
return m
|
||||
}
|
||||
|
||||
func TestPostTweet(t *testing.T) {
|
||||
mux := http.NewServeMux()
|
||||
mux.HandleFunc("upload.twitter.com/1.1/media/upload.json", func(w http.ResponseWriter, req *http.Request) {
|
||||
|
|
Загрузка…
Ссылка в новой задаче