shithub: opossum

Download patch

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

diff: cannot open b/img//null: file does not exist: 'b/img//null'
--- 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