blob: 4aa2cd665d7b65911008cce52663bb19e324efd1 [file] [log] [blame]
// Copyright 2016 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 iconvg
import (
"bytes"
"fmt"
"image"
"image/draw"
"image/png"
"os"
"strings"
"testing"
)
// disassemble returns a disassembly of an encoded IconVG graphic. Users of
// this package aren't expected to want to do this, so it lives in a _test.go
// file, but it can be useful for debugging.
func disassemble(src []byte) (string, error) {
w := new(bytes.Buffer)
p := func(b []byte, format string, args ...interface{}) {
const hex = "0123456789abcdef"
var buf [14]byte
for i := range buf {
buf[i] = ' '
}
for i, x := range b {
buf[3*i+0] = hex[x>>4]
buf[3*i+1] = hex[x&0x0f]
}
w.Write(buf[:])
fmt.Fprintf(w, format, args...)
}
m := Metadata{}
if err := decode(nil, p, &m, false, buffer(src), nil); err != nil {
return "", err
}
return w.String(), nil
}
var (
_ Destination = (*Encoder)(nil)
_ Destination = (*Rasterizer)(nil)
)
// encodePNG is useful for manually debugging the tests.
func encodePNG(dstFilename string, src image.Image) error {
f, err := os.Create(dstFilename)
if err != nil {
return err
}
encErr := png.Encode(f, src)
closeErr := f.Close()
if encErr != nil {
return encErr
}
return closeErr
}
func diffLines(t *testing.T, got, want string) {
gotLines := strings.Split(got, "\n")
wantLines := strings.Split(want, "\n")
for i := 1; ; i++ {
if len(gotLines) == 0 {
t.Errorf("line %d:\ngot %q\nwant %q", i, "", wantLines[0])
return
}
if len(wantLines) == 0 {
t.Errorf("line %d:\ngot %q\nwant %q", i, gotLines[0], "")
return
}
g, w := gotLines[0], wantLines[0]
gotLines = gotLines[1:]
wantLines = wantLines[1:]
if g != w {
t.Errorf("line %d:\ngot %q\nwant %q", i, g, w)
return
}
}
}
func rasterizeASCIIArt(width int, encoded []byte) (string, error) {
dst := image.NewAlpha(image.Rect(0, 0, width, width))
var z Rasterizer
z.SetDstImage(dst, dst.Bounds(), draw.Src)
if err := Decode(&z, encoded, nil); err != nil {
return "", err
}
const asciiArt = ".++8"
buf := make([]byte, 0, width*(width+1))
for y := 0; y < width; y++ {
for x := 0; x < width; x++ {
a := dst.AlphaAt(x, y).A
buf = append(buf, asciiArt[a>>6])
}
buf = append(buf, '\n')
}
return string(buf), nil
}
func TestDisassembleActionInfo(t *testing.T) {
got, err := disassemble(actionInfoIconVG)
if err != nil {
t.Fatal(err)
}
want := strings.Join([]string{
"89 49 56 47 Magic identifier",
"02 Number of metadata chunks: 1",
"0a Metadata chunk length: 5",
"00 Metadata Identifier: 0 (viewBox)",
"50 -24",
"50 -24",
"b0 +24",
"b0 +24",
"c0 Start path, filled with CREG[CSEL-0]; M (absolute moveTo)",
"80 +0",
"58 -20",
"a0 C (absolute cubeTo), 1 reps",
"cf cc 30 c1 -11.049999",
"58 -20",
"58 -20",
"cf cc 30 c1 -11.049999",
"58 -20",
"80 +0",
"91 s (relative smooth cubeTo), 2 reps",
"37 33 0f 41 +8.950001",
"a8 +20",
"a8 +20",
"a8 +20",
" s (relative smooth cubeTo), implicit",
"a8 +20",
"37 33 0f c1 -8.950001",
"a8 +20",
"58 -20",
"80 S (absolute smooth cubeTo), 1 reps",
"cf cc 30 41 +11.049999",
"58 -20",
"80 +0",
"58 -20",
"e3 z (closePath); m (relative moveTo)",
"84 +2",
"bc +30",
"e7 h (relative horizontal lineTo)",
"78 -4",
"e8 V (absolute vertical lineTo)",
"7c -2",
"e7 h (relative horizontal lineTo)",
"88 +4",
"e9 v (relative vertical lineTo)",
"98 +12",
"e3 z (closePath); m (relative moveTo)",
"80 +0",
"60 -16",
"e7 h (relative horizontal lineTo)",
"78 -4",
"e9 v (relative vertical lineTo)",
"78 -4",
"e7 h (relative horizontal lineTo)",
"88 +4",
"e9 v (relative vertical lineTo)",
"88 +4",
"e1 z (closePath); end path",
}, "\n") + "\n"
if got != want {
t.Errorf("got:\n%s\nwant:\n%s", got, want)
diffLines(t, got, want)
}
}
func TestDecodeActionInfo(t *testing.T) {
got, err := rasterizeASCIIArt(24, actionInfoIconVG)
if err != nil {
t.Fatal(err)
}
want := strings.Join([]string{
"........................",
"........................",
"........++8888++........",
"......+8888888888+......",
".....+888888888888+.....",
"....+88888888888888+....",
"...+8888888888888888+...",
"...88888888..88888888...",
"..+88888888..88888888+..",
"..+888888888888888888+..",
"..88888888888888888888..",
"..888888888..888888888..",
"..888888888..888888888..",
"..888888888..888888888..",
"..+88888888..88888888+..",
"..+88888888..88888888+..",
"...88888888..88888888...",
"...+8888888888888888+...",
"....+88888888888888+....",
".....+888888888888+.....",
"......+8888888888+......",
"........++8888++........",
"........................",
"........................",
}, "\n") + "\n"
if got != want {
t.Errorf("got:\n%s\nwant:\n%s", got, want)
diffLines(t, got, want)
}
}