ref: 0a38e51ad3bb7965942bdceb5614d332d76b27bf
parent: 5d909a48ef984b1f8b412acc65222f74deafe139
author: Philip Silva <philip.silva@protonmail.com>
date: Sun Dec 13 14:25:34 EST 2020
img package for <img> and background-images
--- a/browser/browser.go
+++ b/browser/browser.go
@@ -2,15 +2,11 @@
import (
"9fans.net/go/draw"
- "bytes"
- "encoding/base64"
"errors"
"fmt"
- "github.com/nfnt/resize"
"golang.org/x/net/html"
"golang.org/x/net/publicsuffix"
"image"
- "image/jpeg"
"io/ioutil"
"net/http"
"net/http/cookiejar"
@@ -17,6 +13,7 @@
"net/url"
"opossum"
"opossum/domino"
+ "opossum/img"
"opossum/logger"
"opossum/nodes"
"opossum/style"
@@ -134,40 +131,11 @@
return img
}
-func parseDataUri(addr string) (data []byte, err error) {- if strings.Contains(addr, "charset=UTF-8") {- return nil, fmt.Errorf("cannot handle charset")- }
- parts := strings.Split(addr, ",")
- e := base64.RawStdEncoding
- if strings.HasSuffix(addr, "=") {- e = base64.StdEncoding
- }
- if data, err = e.DecodeString(parts[1]); err != nil {- return nil, fmt.Errorf("decode %v src: %w", addr, err)- }
- return
-}
-
func newImage(display *draw.Display, n nodes.Node) (ui duit.UI, err error) {src := attr(*n.DomSubtree, "src")
if src == "" { return nil, fmt.Errorf("no src in %+v", n.Attr)}
- var imgUrl *url.URL
- var data []byte
- if strings.HasPrefix(src, "data:") {- if data, err = parseDataUri(src); err != nil {- return nil, fmt.Errorf("parse data uri %v: %w", src, err)- }
- } else {- if imgUrl, err = browser.LinkedUrl(src); err != nil {- return nil, err
- }
- if data, _, err = browser.Get(imgUrl); err != nil {- return nil, fmt.Errorf("get %v: %w", imgUrl, err)- }
- }
var w int
var h int
@@ -179,29 +147,16 @@
if ok {h, _ = strconv.Atoi(strings.TrimSuffix(hStr.Value, "px"))
}
- if w != 0 || h != 0 {- image, _, err := image.Decode(bytes.NewReader(data))
- if err != nil {- return nil, fmt.Errorf("decode %v: %w", imgUrl, err)- }
- // check err
-
- newImage := resize.Resize(uint(w), uint(h), image, resize.Lanczos3)
-
- // Encode uses a Writer, use a Buffer if you need the raw []byte
- buf := bytes.NewBufferString("")- if err = jpeg.Encode(buf, newImage, nil); err != nil {- return nil, fmt.Errorf("encode: %w", err)- }
- data = buf.Bytes()
+ r, err := img.Load(browser, src, w, h)
+ if err != nil {+ return nil, fmt.Errorf("load draw image: %w", err)}
- r := bytes.NewReader(data)
- log.Printf("Read %v...", imgUrl)+ log.Printf("Read %v...", src)img, err := duit.ReadImage(display, r)
if err != nil {- return nil, fmt.Errorf("duit read image: %w (len=%v)", err, len(data))+ return nil, fmt.Errorf("duit read image: %w", err)}
- log.Printf("Done reading %v", imgUrl)+ log.Printf("Done reading %v", src) return &Element{ UI: &Image{ Image: &duit.Image{--- a/browser/browser_test.go
+++ b/browser/browser_test.go
@@ -16,20 +16,6 @@
expect string
}
-func TestParseDataUri(t *testing.T) {- srcs := []string{"data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP//yH5BAEAAAAALAAAAAABAAEAAAIBRAA7",- "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAAC0lEQVR42mNgYAAAAAMAASsJTYQAAAAASUVORK5CYII=",
- }
-
- for _, src := range srcs {- data, err := parseDataUri(src)
- if err != nil {- t.Fatalf(err.Error())
- }
- t.Logf("%v", data)- }
-}
-
func TestLinkedUrl(t *testing.T) { items := []item{ item{--- a/cmd/browse/main.go
+++ b/cmd/browse/main.go
@@ -8,6 +8,7 @@
"opossum"
"opossum/browser"
"opossum/domino"
+ "opossum/img"
"opossum/logger"
"opossum/style"
"opossum/nodes"
@@ -48,6 +49,7 @@
log.Printf("w'=%v", dui.Scale(w)) log.Printf("kid=%v", dui.Top.R)browser.SetLogger(log)
+ img.SetLogger(log)
opossum.SetLogger(log)
nodes.SetLogger(log)
b := browser.NewBrowser(dui, *startPage)
--- /dev/null
+++ b/img/img.go
@@ -1,0 +1,78 @@
+package img
+
+import (
+ //"9fans.net/go/draw"
+ "bytes"
+ "github.com/nfnt/resize"
+ "encoding/base64"
+ "fmt"
+ //"github.com/mjl-/duit"
+ "image"
+ "image/jpeg"
+ "io"
+ "opossum"
+ "opossum/logger"
+ "strings"
+ "net/url"
+
+ _ "image/gif"
+ _ "image/jpeg"
+ _ "image/png"
+)
+
+var log *logger.Logger
+
+func SetLogger(l *logger.Logger) {+ log = l
+}
+
+func parseDataUri(addr string) (data []byte, err error) {+ if strings.Contains(addr, "charset=UTF-8") {+ return nil, fmt.Errorf("cannot handle charset")+ }
+ parts := strings.Split(addr, ",")
+ e := base64.RawStdEncoding
+ if strings.HasSuffix(addr, "=") {+ e = base64.StdEncoding
+ }
+ if data, err = e.DecodeString(parts[1]); err != nil {+ return nil, fmt.Errorf("decode %v src: %w", addr, err)+ }
+ return
+}
+
+// Load and resize to w and h if != 0
+func Load(f opossum.Fetcher, src string, w, h int) (r io.Reader, err error) {+ var imgUrl *url.URL
+ var data []byte
+ if strings.HasPrefix(src, "data:") {+ if data, err = parseDataUri(src); err != nil {+ return nil, fmt.Errorf("parse data uri %v: %w", src, err)+ }
+ } else {+ if imgUrl, err = f.LinkedUrl(src); err != nil {+ return nil, err
+ }
+ if data, _, err = f.Get(imgUrl); err != nil {+ return nil, fmt.Errorf("get %v: %w", imgUrl, err)+ }
+ }
+
+ if w != 0 || h != 0 {+ image, _, err := image.Decode(bytes.NewReader(data))
+ if err != nil {+ return nil, fmt.Errorf("decode %v: %w", imgUrl, err)+ }
+ // check err
+
+ newImage := resize.Resize(uint(w), uint(h), image, resize.Lanczos3)
+
+ // Encode uses a Writer, use a Buffer if you need the raw []byte
+ buf := bytes.NewBufferString("")+ if err = jpeg.Encode(buf, newImage, nil); err != nil {+ return nil, fmt.Errorf("encode: %w", err)+ }
+ data = buf.Bytes()
+ }
+ return bytes.NewReader(data), nil
+}
--- /dev/null
+++ b/img/img_test.go
@@ -1,0 +1,25 @@
+package img
+
+import (
+ "opossum/logger"
+ "testing"
+)
+
+func init() {+ SetLogger(&logger.Logger{})+}
+
+func TestParseDataUri(t *testing.T) {+ srcs := []string{"data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP//yH5BAEAAAAALAAAAAABAAEAAAIBRAA7",+ "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAAC0lEQVR42mNgYAAAAAMAASsJTYQAAAAASUVORK5CYII=",
+ }
+
+ for _, src := range srcs {+ data, err := parseDataUri(src)
+ if err != nil {+ t.Fatalf(err.Error())
+ }
+ t.Logf("%v", data)+ }
+}
+
--- a/style/experimental.go
+++ b/style/experimental.go
@@ -2,12 +2,12 @@
import (
"9fans.net/go/draw"
- "bytes"
"github.com/chris-ramon/douceur/css"
"fmt"
"github.com/mjl-/duit"
"image"
"opossum"
+ "opossum/img"
"strings"
)
@@ -89,7 +89,7 @@
}
}
-func (cs Map) backgroundImage() (img *draw.Image) {+func (cs Map) backgroundImage() (i *draw.Image) {decl, ok := cs.Declarations["background-image"]
if !ok {decl, ok = cs.Declarations["background"]
@@ -102,24 +102,18 @@
return
}
log.Printf("bg img ok")- uri, err := fetcher.LinkedUrl(imgUrl)
+ r, err := img.Load(fetcher, imgUrl, 0, 0)
if err != nil {- log.Errorf("bg img interpret url: %v", err)+ log.Errorf("bg img load %v: %v", imgUrl, err)return nil
}
- buf, contentType, err := fetcher.Get(uri)
- if err != nil {- log.Errorf("bg img get %v (%v): %v", uri, contentType, err)- return nil
- }
- r := bytes.NewReader(buf)
log.Printf("Read %v...", imgUrl)- img, err = duit.ReadImage(dui.Display, r)
+ i, err = duit.ReadImage(dui.Display, r)
if err != nil { log.Errorf("bg read image: %v", err)return
}
- return img
+ return i
}
return
}
\ No newline at end of file
--- a/style/stylesheets.go
+++ b/style/stylesheets.go
@@ -465,10 +465,10 @@
if ok && propVal.Value == "none" {return true
}
- propVal, ok = cs.Declarations["position"]
+ /*propVal, ok = cs.Declarations["position"]
if ok && propVal.Value == "fixed" {return true
- }
+ }*/
propVal, ok = cs.Declarations["clip"]
if ok && strings.ReplaceAll(propVal.Value, " ", "") == "rect(1px,1px,1px,1px)" {return true
--
⑨