ref: 0a38e51ad3bb7965942bdceb5614d332d76b27bf
parent: 5d909a48ef984b1f8b412acc65222f74deafe139
author: Philip Silva <[email protected]>
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