vgeps: implement vg.Canvas.DrawImage
right now, vgeps.Canvas.DrawImage
is just panic-ing.
here is the start of an implementation:
// DrawImage implements the vg.Canvas.DrawImage method.
func (c *Canvas) DrawImage(rect vg.Rectangle, img image.Image) {
var (
width = rect.Size().X.Dots(DPI)
height = rect.Size().Y.Dots(DPI)
iwidth = img.Bounds().Dx()
iheight = img.Bounds().Dy()
)
c.Push()
fmt.Fprintf(c.buf, "\n%%%% Image data\n")
c.Translate(rect.Min)
fmt.Fprintf(c.buf, "%.*g %.*g scale %% scale pixels to points\n", pr, width, pr, height)
fmt.Fprintf(c.buf, "%d %d 8 [%d 0 0 %d 0 0] ", iwidth, iheight, iwidth, iheight)
fmt.Fprintf(c.buf, "%%%% width height colordepth transform\n")
fmt.Fprintf(c.buf, "/datasource currentfile /ASCII85Decode filter /RunLengthDecode filter def\n")
fmt.Fprintf(c.buf, "/datastring %d string def ", iwidth*3)
fmt.Fprintf(c.buf, "%% %d = width * color components\n", iwidth*3)
fmt.Fprintf(c.buf, "{datasource datastring readstring pop}\n")
fmt.Fprintf(c.buf, "false %%%% false == single data source (rgb)\n")
fmt.Fprintf(c.buf, "3 %%%% number of color components\n")
fmt.Fprintf(c.buf, "colorimage\n")
err := encodeEPSData(c.buf, img)
c.Pop()
if err != nil {
panic(fmt.Errorf("vgeps: error encoding EPS data: %v", err))
}
}
func encodeEPSData(w io.Writer, img image.Image) error {
var (
err error
cs = new(bytes.Buffer)
pix [3]byte
imax = img.Bounds().Dx()
jmax = img.Bounds().Dy()
)
if err != nil {
return err
}
for j := 0; j < jmax; j++ {
for i := 0; i < imax; i++ {
r, g, b, a := img.At(i, j).RGBA()
switch a {
case 0:
pix = [3]byte{}
default:
pix[0] = uint8((r * 65535 / a) >> 8)
pix[1] = uint8((g * 65535 / a) >> 8)
pix[2] = uint8((b * 65535 / a) >> 8)
}
_, err = cs.Write(pix[:])
if err != nil {
return err
}
}
}
rle := rlEncode(cs.String())
r := bytes.NewReader([]byte(rle))
enc := ascii85.NewEncoder(w)
_, err = io.Copy(enc, r)
if err != nil {
return err
}
err = enc.Close()
if err != nil {
return err
}
_, err = w.Write([]byte("~>\n"))
return err
}
func rlEncode(s string) string {
count := 1
var o bytes.Buffer
var i int
for i = 0; i < len(s)-1; i++ {
if s[i] == s[i+1] {
count++
} else {
o.WriteString(fmt.Sprintf("%d%c", count, s[i]))
count = 1
}
}
o.WriteString(fmt.Sprintf("%d%c", count, s[i]))
return o.String()
}
this was mostly extracted from: https://github.com/eaburns/search/blob/master/graphics/image.cc#L102 https://github.com/eaburns/search/blob/master/utils/encode.cc#L19