ref: 294b8735087508d83c93f56e7991d64a97c3edea
parent: 4d0b99d04d24818c1b1d05ff49ce11b4c1131215
author: Philip Silva <[email protected]>
date: Mon Jan 10 16:50:01 EST 2022
no more superfluous png encoding in between
--- a/browser/browser.go
+++ b/browser/browser.go
@@ -2,7 +2,6 @@
import (
"9fans.net/go/draw"
- "bytes"
"errors"
"fmt"
"github.com/psilva261/opossum"
@@ -200,19 +199,11 @@
return nil, fmt.Errorf("serialize: %w", err)
}
log.Printf("newImage: xml: %v", xml)
- buf, err := img.Svg(xml, n.Width(), n.Height())
- if err == nil {
- var err error
- r := bytes.NewReader(buf)
- i, err = duit.ReadImage(display, r)
- if err != nil {
- return nil, fmt.Errorf("read image %v: %v", xml, err)
- }
-
- goto img_elem
- } else {
+ i, err = img.Svg(dui, xml, n.Width(), n.Height())
+ if err != nil {
return nil, fmt.Errorf("img svg %v: %v", xml, err)
}
+ goto img_elem
} else if n.Data() == "img" {
_, s := srcSet(n)
if s != "" {
@@ -228,16 +219,10 @@
mw, _ := n.CssPx("max-width")
w := n.Width()
h := n.Height()
- r, err := img.Load(browser, src, mw, w, h)
+ i, err = img.Load(dui, browser, src, mw, w, h)
if err != nil {
- return nil, fmt.Errorf("load draw image: %w", err)
+ return nil, fmt.Errorf("load image: %w", err)
}
- log.Printf("Read %v...", src)
- i, err = duit.ReadImage(display, r)
- if err != nil {
- return nil, fmt.Errorf("duit read image: %w", err)
- }
- log.Printf("Done reading %v", src)
imageCache[src] = i
}
--- a/img/img.go
+++ b/img/img.go
@@ -1,17 +1,18 @@
package img
import (
+ "9fans.net/go/draw"
"bytes"
"encoding/base64"
"fmt"
+ "github.com/mjl-/duit"
"github.com/psilva261/opossum"
"github.com/psilva261/opossum/logger"
"github.com/srwiley/oksvg"
"github.com/srwiley/rasterx"
- "golang.org/x/image/draw"
+ xdraw "golang.org/x/image/draw"
"image"
- "image/png"
- "io"
+ imagedraw "image/draw"
"net/url"
"strings"
@@ -151,7 +152,23 @@
// Svg returns the svg+xml encoded as jpg with the sizing defined in
// viewbox unless w and h != 0
-func Svg(data string, w, h int) (bs []byte, err error) {
+func Svg(dui *duit.DUI, data string, w, h int) (ni *draw.Image, err error) {
+ rgba, err := svg(data, w, h)
+ if err != nil {
+ return nil, err
+ }
+ ni, err = dui.Display.AllocImage(rgba.Bounds(), draw.ABGR32, false, draw.White)
+ if err != nil {
+ return nil, fmt.Errorf("allocimage: %s", err)
+ }
+ _, err = ni.Load(rgba.Bounds(), rgba.Pix)
+ if err != nil {
+ return nil, fmt.Errorf("load image: %s", err)
+ }
+ return
+}
+
+func svg(data string, w, h int) (img *image.RGBA, err error) {
data = strings.ReplaceAll(data, "currentColor", "black")
data = strings.ReplaceAll(data, "inherit", "black")
data = quoteAttrs(data)
@@ -171,16 +188,40 @@
rgba := image.NewRGBA(image.Rect(0, 0, w, h))
icon.Draw(rasterx.NewDasher(w, h, rasterx.NewScannerGV(w, h, rgba, rgba.Bounds())), 1)
- buf := bytes.NewBufferString("")
- if err = png.Encode(buf, rgba); err != nil {
- return nil, fmt.Errorf("encode: %w", err)
+ return rgba, nil
+}
+
+// Load and resize to w and h if != 0
+//
+// Stolen from duit.ReadImage
+func Load(dui *duit.DUI, f opossum.Fetcher, src string, maxW, w, h int) (ni *draw.Image, err error) {
+ drawImg, err := load(f, src, maxW, w, h)
+ if err != nil {
+ return nil, err
}
+ var rgba *image.RGBA
+ switch i := drawImg.(type) {
+ case *image.RGBA:
+ rgba = i
+ default:
+ b := drawImg.Bounds()
+ rgba = image.NewRGBA(image.Rectangle{image.ZP, b.Size()})
+ imagedraw.Draw(rgba, rgba.Bounds(), drawImg, b.Min, imagedraw.Src)
+ }
- return buf.Bytes(), nil
+ // todo: package image claims data is in r,g,b,a. who is reversing the bytes? devdraw? will this work on big endian?
+ ni, err = dui.Display.AllocImage(rgba.Bounds(), draw.ABGR32, false, draw.White)
+ if err != nil {
+ return nil, fmt.Errorf("allocimage: %s", err)
+ }
+ _, err = ni.Load(rgba.Bounds(), rgba.Pix)
+ if err != nil {
+ return nil, fmt.Errorf("load image: %s", err)
+ }
+ return
}
-// Load and resize to w and h if != 0
-func Load(f opossum.Fetcher, src string, maxW, w, h int) (r io.Reader, err error) {
+func load(f opossum.Fetcher, src string, maxW, w, h int) (img image.Image, err error) {
var imgUrl *url.URL
var data []byte
var contentType opossum.ContentType
@@ -199,41 +240,38 @@
}
if contentType.IsSvg() {
- data, err = Svg(string(data), w, h)
+ img, err := svg(string(data), w, h)
if err != nil {
return nil, fmt.Errorf("svg: %v", err)
}
- } else if maxW != 0 || w != 0 || h != 0 {
- img, _, err := image.Decode(bytes.NewReader(data))
+ return img, nil
+ } else {
+ img, _, err = image.Decode(bytes.NewReader(data))
if err != nil {
return nil, fmt.Errorf("decode %v: %w", imgUrl, err)
}
+ if maxW != 0 || w != 0 || h != 0 {
+ dx := img.Bounds().Max.X
+ dy := img.Bounds().Max.Y
+ log.Printf("dx,dy=%v,%v", dx, dy)
+ if w == 0 && h == 0 && 0 < maxW && maxW < dx {
+ w = maxW
+ }
- dx := img.Bounds().Max.X
- dy := img.Bounds().Max.Y
- log.Printf("dx,dy=%v,%v", dx, dy)
- if w == 0 && h == 0 && 0 < maxW && maxW < dx {
- w = maxW
- }
+ newX, newY, skip := newSizes(dx, dy, w, h)
- newX, newY, skip := newSizes(dx, dy, w, h)
-
- if !skip {
- log.Printf("resize image to %v x %v", newX, newY)
- dst := image.NewRGBA(image.Rect(0, 0, newX, newY))
- draw.NearestNeighbor.Scale(dst, dst.Rect, img, img.Bounds(), draw.Over, nil)
- buf := bytes.NewBufferString("")
-
- if err = png.Encode(buf, dst); err != nil {
- return nil, fmt.Errorf("encode: %w", err)
+ if !skip {
+ log.Printf("resize image to %v x %v", newX, newY)
+ dst := image.NewRGBA(image.Rect(0, 0, newX, newY))
+ xdraw.NearestNeighbor.Scale(dst, dst.Rect, img, img.Bounds(), xdraw.Over, nil)
+ img = dst
+ } else {
+ log.Printf("skip resizing")
}
- data = buf.Bytes()
- } else {
- log.Printf("skip resizing")
}
}
- return bytes.NewReader(data), nil
+ return img, nil
}
func newSizes(oldX, oldY, wantedX, wantedY int) (newX, newY int, skip bool) {
--- a/img/img_test.go
+++ b/img/img_test.go
@@ -46,7 +46,7 @@
</svg>
`
- _, err := Svg(xml, 0, 0)
+ _, err := svg(xml, 0, 0)
if err != nil {
t.Fatalf(err.Error())
}
@@ -61,7 +61,7 @@
`
xml = `<svg xmlns=http://www.w3.org/2000/svg viewBox=0 0 37 37 fill=#000000><path class=border fill=blue stroke=green/></svg>`
- _, err := Svg(xml, 0, 0)
+ _, err := svg(xml, 0, 0)
if err != nil {
t.Fatalf(err.Error())
}
@@ -110,13 +110,9 @@
t.Fail()
}
b := &MockBrowser{buf.Bytes()}
- r, err := Load(b, "", mw, w, h)
+ img, err := load(b, "", mw, w, h)
if err != nil {
t.Errorf("load: %v", err)
- }
- img, _, err := image.Decode(r)
- if err != nil {
- t.Errorf("decode")
}
dx := img.Bounds().Max.X
dy := img.Bounds().Max.Y
--- a/style/experimental.go
+++ b/style/experimental.go
@@ -3,7 +3,6 @@
import (
"9fans.net/go/draw"
"fmt"
- "github.com/mjl-/duit"
"github.com/psilva261/opossum"
"github.com/psilva261/opossum/img"
"github.com/psilva261/opossum/logger"
@@ -194,18 +193,12 @@
w := cs.Width()
h := cs.Height()
- r, err := img.Load(fetcher, imgUrl, 0, w, h)
+ var err error
+ i, err = img.Load(dui, fetcher, imgUrl, 0, w, h)
if err != nil {
log.Errorf("bg img load %v: %v", imgUrl, err)
- return nil
- }
-
- i, err = duit.ReadImage(dui.Display, r)
- if err != nil {
- log.Errorf("bg read image %v: %v", imgUrl, err)
return
}
- return i
}
return
}