Skip to content

Commit

Permalink
shiny/iconvg: implement suggested palettes.
Browse files Browse the repository at this point in the history
Change-Id: I5bd5f0d1c0c5c83be0216eb149c87fbce595d7ab
Reviewed-on: https://go-review.googlesource.com/31374
Reviewed-by: David Crawshaw <crawshaw@golang.org>
  • Loading branch information
nigeltao committed Oct 22, 2016
1 parent 8fd4879 commit fb66711
Show file tree
Hide file tree
Showing 8 changed files with 96 additions and 10 deletions.
3 changes: 2 additions & 1 deletion shiny/iconvg/color.go
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,8 @@ func CRegColor(i uint8) Color { return Color{ColorTypeCReg, color.RGBA{R: i & 0x
//
// To blend a Color that is not encodable as a 1 byte color, first load that
// Color into a CREG color register, then call CRegColor to produce a Color
// that is encodable as a 1 byte color.
// that is encodable as a 1 byte color. See testdata/favicon.ivg for an
// example.
//
// See the "Colors" section in the package documentation for details.
func BlendColor(t, c0, c1 uint8) Color { return Color{ColorTypeBlend, color.RGBA{R: t, G: c0, B: c1}} }
Expand Down
11 changes: 9 additions & 2 deletions shiny/iconvg/decode_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -136,7 +136,7 @@ var testdataTestCases = []struct {
{"testdata/blank", ""},
{"testdata/cowbell", ""},
{"testdata/elliptical", ""},
{"testdata/favicon", ""},
{"testdata/favicon", ";pink"},
{"testdata/gradient", ""},
{"testdata/lod-polygon", ";64"},
{"testdata/video-005.primitive", ""},
Expand Down Expand Up @@ -198,10 +198,17 @@ func TestRasterizer(t *testing.T) {
height = int(float32(length) * dy / dx)
}

opts := &DecodeOptions{}
if variant == "pink" {
pal := DefaultPalette
pal[0] = color.RGBA{0xfe, 0x76, 0xea, 0xff}
opts.Palette = &pal
}

got := image.NewRGBA(image.Rect(0, 0, width, height))
var z Rasterizer
z.SetDstImage(got, got.Bounds(), draw.Src)
if err := Decode(&z, ivgData, nil); err != nil {
if err := Decode(&z, ivgData, opts); err != nil {
t.Errorf("%s %q variant: Decode: %v", tc.filename, variant, err)
continue
}
Expand Down
48 changes: 47 additions & 1 deletion shiny/iconvg/encode.go
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,53 @@ func (e *Encoder) Reset(m Metadata) {
}

if mcSuggestedPalette {
panic("TODO: encode mcSuggestedPalette")
n := 63
for ; n >= 0 && m.Palette[n] == (color.RGBA{0x00, 0x00, 0x00, 0xff}); n-- {
}

// Find the shortest encoding that can represent all of m.Palette's n+1
// explicit colors.
enc1, enc2, enc3 := true, true, true
for _, c := range m.Palette[:n+1] {
if enc1 && (!is1(c.R) || !is1(c.G) || !is1(c.B) || !is1(c.A)) {
enc1 = false
}
if enc2 && (!is2(c.R) || !is2(c.G) || !is2(c.B) || !is2(c.A)) {
enc2 = false
}
if enc3 && (c.A != 0xff) {
enc3 = false
}
}

e.altBuf = e.altBuf[:0]
e.altBuf.encodeNatural(midSuggestedPalette)
if enc1 {
e.altBuf = append(e.altBuf, byte(n)|0x00)
for _, c := range m.Palette[:n+1] {
x, _ := encodeColor1(RGBAColor(c))
e.altBuf = append(e.altBuf, x)
}
} else if enc2 {
e.altBuf = append(e.altBuf, byte(n)|0x40)
for _, c := range m.Palette[:n+1] {
x, _ := encodeColor2(RGBAColor(c))
e.altBuf = append(e.altBuf, x[0], x[1])
}
} else if enc3 {
e.altBuf = append(e.altBuf, byte(n)|0x80)
for _, c := range m.Palette[:n+1] {
e.altBuf = append(e.altBuf, c.R, c.G, c.B)
}
} else {
e.altBuf = append(e.altBuf, byte(n)|0xc0)
for _, c := range m.Palette[:n+1] {
e.altBuf = append(e.altBuf, c.R, c.G, c.B, c.A)
}
}

e.buf.encodeNatural(uint32(len(e.altBuf)))
e.buf = append(e.buf, e.altBuf...)
}
}

Expand Down
30 changes: 28 additions & 2 deletions shiny/iconvg/encode_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -351,11 +351,37 @@ var faviconSVGData = []struct {
}}

func TestEncodeFavicon(t *testing.T) {
// Set up a base color for theming the favicon, gopher blue by default.
pal := DefaultPalette
pal[0] = faviconColors[0] // color.RGBA{0x76, 0xe1, 0xfe, 0xff}

var e Encoder
e.Reset(Metadata{
ViewBox: DefaultViewBox,
Palette: pal,
})

// The favicon graphic also uses a dark version of that base color. blend
// is 75% dark (CReg[63]) and 25% the base color (pal[0]).
dark := color.RGBA{0x23, 0x1d, 0x1b, 0xff}
blend := BlendColor(0x40, 0xff, 0x80)

for i, c := range faviconColors[:2] {
e.SetCReg(uint8(i), false, RGBAColor(c))
// First, set CReg[63] to dark, then set CReg[63] to the blend of that dark
// color with pal[0].
e.SetCReg(1, false, RGBAColor(dark))
e.SetCReg(1, false, blend)

// Check that, for the suggested palette, blend resolves to the
// (non-themable) SVG file's faviconColors[1].
got := blend.Resolve(&pal, &[64]color.RGBA{
63: dark,
})
want := faviconColors[1]
if got != want {
t.Fatalf("Blend:\ngot %#02x\nwant %#02x", got, want)
}

// Set aside the remaining, non-themable colors.
remainingColors := faviconColors[2:]

seenFCI2 := false
Expand Down
2 changes: 1 addition & 1 deletion shiny/iconvg/testdata/README
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ favicon.ivg is an IconVG version of that SVG file.

favicon.ivg.disassembly is a disassembly of that IconVG file.

favicon.png is a rendering of that IconVG file.
favicon.png and favicon.pink.png are renderings of that IconVG file.



Expand Down
Binary file modified shiny/iconvg/testdata/favicon.ivg
Binary file not shown.
12 changes: 9 additions & 3 deletions shiny/iconvg/testdata/favicon.ivg.disassembly
Original file line number Diff line number Diff line change
@@ -1,9 +1,15 @@
89 49 56 47 IconVG Magic identifier
00 Number of metadata chunks: 0
90 Set CREG[CSEL-0] to a 3 byte (direct) color
02 Number of metadata chunks: 1
0a Metadata chunk length: 5
02 Metadata Identifier: 1 (suggested palette)
80 1 palette colors, 3 bytes per color
76 e1 fe RGBA 76e1feff
91 Set CREG[CSEL-1] to a 3 byte (direct) color
38 4e 54 RGBA 384e54ff
23 1d 1b RGBA 231d1bff
a1 Set CREG[CSEL-1] to a 3 byte (indirect) color
40 blend 191:64 c0:c1
ff c0: CREG[63]
80 c1: customPalette[0]
c1 Start path, filled with CREG[CSEL-1]; M (absolute moveTo)
31 80 +0.1875
44 -30
Expand Down
Binary file added shiny/iconvg/testdata/favicon.pink.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.

0 comments on commit fb66711

Please sign in to comment.