// Colors returns an array of colors based on a HTTP request. // It follows some rules: // - if the URL has it's own colors using the 'colors' parameter we return those. // e.g: some/url?colors=FFFFFF&colors=222222 // - if the URL has a theme defined using the 'theme' parameter, we return those colors. // if the theme does not exist we use the base theme. // if the number of colors is specified usign the 'numcolors' parameter, // we only return the number of colors specified. // e.g: some/url?theme=frogideas // returns an array with the first 2 colors that define the 'frogideas' theme. // e.g: some/url?theme=frogideas&numcolors=4 // returns an array with the first 4 colors that define the 'frogideas' theme. // - if the URL has a background and/or a foreground defined by usign parameters 'bg' and 'fg' // we return those. // e.g: some/url?bg=FFFFFF&fg=222222 // - if you use parameter 'inv' you can invert the colors. // This is true only if the number of colors is equal to 2 and you use 'theme' colors or default ones. // e.g: some/url?inv=1 // some/url?theme=frogideas&numcolors=2&inv=1 func Colors(r *http.Request) (colors []color.RGBA) { if newColors, err := UserColors(r); err == nil { return newColors } th := Theme(r) if th == "base" { bg, fg := ExtraColors(r) colors = append(colors, bg, fg) } else { m := tgColors.MapOfColorThemes() if _, ok := m[th]; ok { n := NumColors(r) colors = append(colors, m[th][0:n]...) } else { colors = append(colors, m["base"]...) } } if len(colors) == 2 && Inverse(r) { swap(&colors) } if order := Order(r); len(order) > 0 { ReOrder(order, &colors) } return }
// Theme handler builds an image with the colors of a theme // the theme is defined by keyword :theme // url: "/themes/:theme" func Theme(w http.ResponseWriter, r *http.Request) { var err error var th string if th, _ = route.Context.Get(r, "theme"); err != nil { th = "base" } colorMap := colors.MapOfColorThemes() var theme []color.RGBA if val, ok := colorMap[th]; ok { theme = val } else { theme = colorMap["base"] } width := extract.WidthOrDefault(r, 20*len(theme)) height := extract.HeightOrDefault(r, 34) if f := extract.Format(r); f == format.JPEG { m := image.NewRGBA(image.Rect(0, 0, width, height)) squares.Palette(m, theme) var img image.Image = m write.ImageJPEG(w, &img) } else if f == format.SVG { write.ImageSVG(w) squares.PaletteSVG(w, theme, width, height) } }
func TestGColors(t *testing.T) { t.Parallel() colorMap := tgColors.MapOfColorThemes() tests := []struct { title string url string gColors []color.RGBA }{ { "test wrong input", "http://www.tg.c?colors=foo&colors=bar", colorMap["base"], }, { "test no input", "http://www.tg.c", colorMap["base"], }, { "test good input", "http://www.tg.c?colors=aaaaaa&colors=bbbbbb", []color.RGBA{ {170, 170, 170, 255}, {187, 187, 187, 255}, }, }, { "test good input", "http://www.tg.c?colors=ffffff&colors=000000&colors=000000", []color.RGBA{ {255, 255, 255, 255}, {0, 0, 0, 255}, {0, 0, 0, 255}, }[1:3], }, { "test with theme", "http://www.tg.c?theme=frogideas", colorMap["frogideas"][1:3], }, } for _, test := range tests { t.Log(test.title) r := &http.Request{Method: "GET"} r.URL, _ = url.Parse(test.url) gColors := GColors(r) if len(gColors) != len(test.gColors) { t.Errorf("expected %d array got %d", len(test.gColors), len(gColors)) } for i := 0; i < len(test.gColors); i++ { if test.gColors[i] != gColors[i] { t.Errorf("expected %v array got %v", test.gColors[i], gColors[i]) } } } }
// GColors returns an array of colors based on a HTTP request. // It follows some rules: // - if the URL has it's a theme defined by using the 'theme' parameter we return // all the colors of that theme but the first one. // - if the URL has it's own colors using the 'colors' parameter we return all of // those colors but the first one defined. If the array is less or equal to 2 we return the // full array. // e.g: some/url?colors=FFFFFF&colors=222222&colors=111111 gives you the // following array [111111, 222222] // - otherwise we return Colors(r) func GColors(r *http.Request) (gColors []color.RGBA) { theme := Theme(r) if theme != "base" { colorMap := tgColors.MapOfColorThemes() if _, ok := colorMap[theme]; ok { return colorMap[theme][1:3] } } if newColors, err := UserColors(r); err == nil { if len(newColors) > 2 { gColors = newColors[1:] } else { gColors = newColors } } else { gColors = Colors(r) } return }
// Checkerboard is the handler for /checkerboard // build a 6x6 checkerboard with alternate black and white colors. func Checkerboard(w http.ResponseWriter, r *http.Request) { size := extract.Size(r) theme := extract.Theme(r) colorMap := colors.MapOfColorThemes() var c1, c2 color.RGBA if val, ok := colorMap[theme]; ok { c1 = val[0] c2 = val[1] } else { c1 = colorMap["base"][0] c2 = colorMap["base"][1] } if f := extract.Format(r); f == format.JPEG { m := image.NewRGBA(image.Rect(0, 0, size, size)) squares.Grid(m, c1, c2) var img image.Image = m write.ImageJPEG(w, &img) } else if f == format.SVG { write.ImageSVG(w) squares.GridSVG(w, c1, c2, size) } }
func TestColors(t *testing.T) { t.Parallel() colorMap := tgColors.MapOfColorThemes() tests := []struct { title string url string colors []color.RGBA }{ { "test wrong input", "http://www.tg.c?colors=foo&colors=bar", colorMap["base"], }, { "test no input", "http://www.tg.c", colorMap["base"], }, { "test good input", "http://www.tg.c?colors=ffffff&colors=000000", []color.RGBA{ {255, 255, 255, 255}, {0, 0, 0, 255}, }, }, { "test good input with theme", "http://www.tg.c?theme=frogideas", colorMap["frogideas"][0:2], }, { "test good input with theme and num color", "http://www.tg.c?theme=frogideas&numcolors=4", colorMap["frogideas"], }, { "test good input with theme and order array", "http://www.tg.c?theme=frogideas&numcolors=4&order=3&order=2&order=1&order=0", []color.RGBA{ colorMap["frogideas"][3], colorMap["frogideas"][2], colorMap["frogideas"][1], colorMap["frogideas"][0], }, }, { "test bad theme", "http://www.tg.c?theme=bad", colorMap["base"], }, } for _, test := range tests { t.Log(test.title) r := &http.Request{Method: "GET"} r.URL, _ = url.Parse(test.url) colors := Colors(r) if len(colors) != len(test.colors) { t.Errorf("expected %d array got %d", len(test.colors), len(colors)) } for i := 0; i < len(test.colors); i++ { if test.colors[i] != colors[i] { t.Errorf("expected %+v array got %+v", test.colors[i], colors[i]) } } } }