ref: 6fea339d0e40d598f093146c0d096b64e2e10c91
parent: f00d509c3efd320c795af6964d861a73761da3e9
author: Philip Silva <philip.silva@protonmail.com>
date: Tue Aug 3 06:54:27 EDT 2021
Some code for gradients - upgrade to more recent plan9 go library
--- a/browser/browser.go
+++ b/browser/browser.go
@@ -673,7 +673,7 @@
maxX := self.R.Dx()
maxY := self.R.Dy()
if 5 <= x && x <= (maxX-5) && 5 <= y && y <= (maxY-5) && el.IsLink {
- //dui.Display.SetCursor(&draw.Cursor{
+ //dui.Display.SwitchCursor(&draw.Cursor{
// Set: cursor,
//})
if m.Buttons == 0 {
@@ -681,7 +681,7 @@
return r
}
} else {
- dui.Display.SetCursor(nil)
+ dui.Display.SwitchCursor(nil)
}
return el.UI.Mouse(dui, self, m, origM, orig)
--- a/go.mod
+++ b/go.mod
@@ -2,11 +2,11 @@
go 1.16
-replace 9fans.net/go v0.0.0-00010101000000-000000000000 => github.com/psilva261/go v0.0.0-20210710174246-83fbc9c615a4
+replace 9fans.net/go v0.0.0-00010101000000-000000000000 => github.com/psilva261/go v0.0.0-20210802153818-99e868f39f77
-replace 9fans.net/go v0.0.2 => github.com/psilva261/go v0.0.0-20210710174246-83fbc9c615a4
+replace 9fans.net/go v0.0.2 => github.com/psilva261/go v0.0.0-20210802153818-99e868f39f77
-replace github.com/mjl-/duit v0.0.0-20200330125617-580cb0b2843f => github.com/psilva261/duit v0.0.0-20210627123547-8bc19650d4a2
+replace github.com/mjl-/duit v0.0.0-20200330125617-580cb0b2843f => github.com/psilva261/duit v0.0.0-20210802155600-7e8fedefa7ba
replace github.com/knusbaum/go9p v1.17.0 => github.com/psilva261/go9p-1 v1.17.1-0.20210620075710-0428cf31f72f
--- a/go.sum
+++ b/go.sum
@@ -22,10 +22,10 @@
github.com/gorilla/css v1.0.0/go.mod h1:Dn721qIggHpt4+EFCcTLTU/vk5ySda2ReITrtgBl60c=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
-github.com/psilva261/duit v0.0.0-20210627123547-8bc19650d4a2 h1:XVUpKOs8MDCaGCyyrpr5an4rflKIpJpMq/76XhqdC5I=
-github.com/psilva261/duit v0.0.0-20210627123547-8bc19650d4a2/go.mod h1:bCuFm7lhAl9wLyLCC6E4RVLDpAv7bWfnTMeDd+C4OQ8=
-github.com/psilva261/go v0.0.0-20210710174246-83fbc9c615a4 h1:sejI8Sc8MAeHriTWRzGOxQFJanm0tC9hVbneobr/KHM=
-github.com/psilva261/go v0.0.0-20210710174246-83fbc9c615a4/go.mod h1:AWpRSZZ474OlNPxa7mOyFZ6Ceg9FRel9f+EONmhPbu0=
+github.com/psilva261/duit v0.0.0-20210802155600-7e8fedefa7ba h1:p8M5yp22QzefbIU3xGERHYnGxlfkcjWV6dh62xIO0U4=
+github.com/psilva261/duit v0.0.0-20210802155600-7e8fedefa7ba/go.mod h1:Ukumf0oazEttGwdWuN21g81jNap4NVccEgKuAUAqkf0=
+github.com/psilva261/go v0.0.0-20210802153818-99e868f39f77 h1:Oy+TCTt29ad3OMoPd3z1pb8YSrmQTAE5SyC8pdM2GDc=
+github.com/psilva261/go v0.0.0-20210802153818-99e868f39f77/go.mod h1:AWpRSZZ474OlNPxa7mOyFZ6Ceg9FRel9f+EONmhPbu0=
github.com/psilva261/go9p-1 v1.17.1-0.20210620075710-0428cf31f72f h1:gJVK1NhzFXZye5ki4bvyu8dzo0qIckxTf68Vm+Qh4BI=
github.com/psilva261/go9p-1 v1.17.1-0.20210620075710-0428cf31f72f/go.mod h1:HtMoJKqZUe1Oqag5uJqG5RKQ9gWPSP+wolsnLLv44r8=
github.com/srwiley/oksvg v0.0.0-20210320200257-875f767ac39a h1:Lhe6HPtH4ndWfV56fWc4/yQhOP3vEGlwl5nfPyBxUAg=
--- a/style/experimental.go
+++ b/style/experimental.go
@@ -31,14 +31,19 @@
func (cs Map) BoxBackground() (i *draw.Image, err error) {
var bgImg *draw.Image
- bgImg = cs.backgroundImage()
+ if bgImg = cs.backgroundImage(); bgImg != nil {
+ return bgImg, nil
+ }
+ if bgImg = cs.BackgroundGradient(); bgImg != nil {
+ return bgImg, nil
+ }
+
if bgImg == nil {
bgColor, ok := cs.backgroundColor()
if !ok {
return
}
- log.Printf("bgColor=%+v", bgColor)
i, ok = colorCache[bgColor]
if !ok {
var err error
@@ -55,17 +60,17 @@
}
func (cs Map) backgroundColor() (c draw.Color, ok bool) {
- _, ok = cs.Declarations["background-color"]
+ d, ok := cs.Declarations["background-color"]
if ok {
- c, ok = cs.colorHex("background-color")
+ c, ok = colorHex(d.Value)
if !ok {
return
}
return c, true
}
- _, ok = cs.Declarations["background"]
+ d, ok = cs.Declarations["background"]
if ok {
- c, ok = cs.colorHex("background")
+ c, ok = colorHex(d.Value)
if !ok {
return
}
@@ -74,6 +79,82 @@
return
}
+// BackgroundGradient is a stub implemention right now (TODO)
+func (cs Map) BackgroundGradient() (img *draw.Image) {
+ var err error
+ c, ok := cs.backgroundGradient()
+ if !ok {
+ return
+ }
+ img, err = dui.Display.AllocImage(image.Rect(0, 0, 10, 10), draw.ARGB32, true, c)
+ if err != nil {
+ log.Errorf("alloc img: %v", err)
+ img = nil
+ }
+ return
+}
+
+func (cs Map) backgroundGradient() (c draw.Color, ok bool) {
+ d, ok := cs.Declarations["background"]
+ if !ok {
+ return
+ }
+ v := strings.TrimSpace(d.Value)
+ if strings.HasPrefix(v, "linear-gradient(") {
+ v = strings.TrimPrefix(v, "linear-gradient(")
+ } else {
+ return
+ }
+ v = strings.TrimSuffix(v, ")")
+
+ colors := make([]draw.Color, 0, 2)
+
+ for i := 0; i < len(v); {
+ m := strings.Index(v[i:], ",")
+ op := strings.Index(v[i:], "(")
+ cl := strings.Index(v[i:], ")")
+ if m < 0 {
+ break
+ }
+ var arg string
+ if cl > 0 && op < m && m < cl {
+ arg = v[i:i+cl+1]
+ i += cl + 1
+ } else {
+ arg = v[i:i+m]
+ i += m + 1
+ }
+
+ arg = strings.ReplaceAll(arg, " ", "")
+ c, ok := colorHex(arg)
+ if ok {
+ colors = append(colors, c)
+ }
+ }
+ if len(colors) >= 2 {
+ from := colors[0]
+ to := colors[1]
+ c := linearGradient(from, to, 0.5, 0, 1)
+ return c, true
+ }
+ return
+}
+
+func linearGradient(from, to draw.Color, x, y, xmax float64) (c draw.Color) {
+ fr, fg, fb, fa := from.RGBA()
+ tr, tg, tb, ta := to.RGBA()
+ d := x/xmax
+ r := uint32(float64(fr) + d*float64(tr-fr))
+ g := uint32(float64(fg) + d*float64(tg-fg))
+ b := uint32(float64(fb) + d*float64(tb-fb))
+ a := uint32(float64(fa) + d*float64(ta-fa))
+ cc := (r/256) << 24
+ cc = cc | ((g/256) << 16)
+ cc = cc | ((b/256) << 8)
+ cc = cc | (a/256)
+ return draw.Color(cc)
+}
+
func backgroundImageUrl(decl css.Declaration) (url string, ok bool) {
if v := decl.Value; strings.Contains(v, "url(") && strings.Contains(v, ")") {
v = strings.ReplaceAll(v, `"`, "")
@@ -80,7 +161,7 @@
v = strings.ReplaceAll(v, `'`, "")
from := strings.Index(v, "url(")
if from < 0 {
- log.Printf("bg img: no url: %v", decl.Value)
+ log.Printf("bg img: no url: %v", v)
return
}
from += len("url(")
@@ -87,13 +168,13 @@
imgUrl := v[from:]
to := strings.Index(imgUrl, ")")
if to < 0 {
- log.Printf("bg img: no ): %v", decl.Value)
+ log.Printf("bg img: no ): %v", v)
return
}
imgUrl = imgUrl[:to]
return imgUrl, true
} else {
- log.Printf("bg img: missing ( or ) '%+v'", decl.Value)
+ log.Printf("bg img: missing ( or ) '%+v'", v)
return
}
}
--- a/style/experimental_test.go
+++ b/style/experimental_test.go
@@ -3,9 +3,14 @@
import (
"9fans.net/go/draw"
"github.com/chris-ramon/douceur/css"
+ "github.com/psilva261/opossum/logger"
"testing"
)
+func init() {
+ log.Debug = true
+}
+
func TestBackgroundImageUrl(t *testing.T) {
suffix := ""
for _, quote := range []string{"", "'", `"`} {
@@ -42,6 +47,30 @@
if b, ok := m.backgroundColor(); !ok || b != d {
t.Fatalf("%v", b)
}
+ }
+ }
+}
+
+func TestBackgroundGradient(t *testing.T) {
+ values := map[string]uint32{
+ "linear-gradient(to right,rgb(10,0,50,1),rgb(200,0,50,1))": 0x690032ff,
+ "linear-gradient(to right,rgb(0,60,60,1),rgba(0,180,180,1))": 0x007878ff,
+ "linear-gradient(to bottom, rgba(40,40,40,1) 0%,rgba(40,40,40,1) 100%)": 0x282828ff,
+ }
+ for v, cc := range values {
+ m := Map{
+ Declarations: make(map[string]css.Declaration),
+ }
+ m.Declarations["background"] = css.Declaration{
+ Property: "background",
+ Value: v,
+ }
+ c, ok := m.backgroundGradient()
+ if !ok {
+ t.Fail()
+ }
+ if uint32(c) != cc {
+ t.Fail()
}
}
}
--- a/style/fonts_plan9.go
+++ b/style/fonts_plan9.go
@@ -26,7 +26,7 @@
// unit tests
return
}
- def := dui.Display.DefaultFont.Name
+ def := dui.Display.Font.Name
ms, err := fontsLike(def)
if err != nil {
log.Errorf("find fonts: %v", err)
--- a/style/stylesheets.go
+++ b/style/stylesheets.go
@@ -176,7 +176,7 @@
}
// for media queries
- if strings.Contains(r.Prelude, "print") {
+ if strings.Contains(r.Prelude, "print") && !strings.Contains(r.Prelude, "screen") {
continue
}
if rMaxWidth.MatchString(r.Prelude) {
@@ -366,96 +366,98 @@
}
func (cs Map) Color() draw.Color {
- h, ok := cs.colorHex("color")
- if !ok {
- return draw.Black
+ if d, ok := cs.Declarations["color"]; ok {
+ if h, ok := colorHex(d.Value); ok {
+ c := draw.Color(h)
+ return c
+ }
}
- c := draw.Color(h)
- return c
+ return draw.Black
}
-func (cs Map) colorHex(cssPropName string) (c draw.Color, ok bool) {
- propVal, ok := cs.Declarations[cssPropName]
- if ok {
- var r, g, b uint32
- if strings.HasPrefix(propVal.Value, "rgb") {
- val := propVal.Value[3:]
- val = strings.TrimPrefix(val, "(")
- val = strings.TrimSuffix(val, ")")
- vals := strings.Split(val, ",")
- rr, err := strconv.ParseInt(vals[0], 10, 32)
+func colorHex(propVal string) (c draw.Color, ok bool) {
+ var r, g, b uint32
+ var x uint32
+ if strings.HasPrefix(propVal, "rgb") {
+ val := propVal[3:]
+ val = strings.TrimPrefix(val, "a")
+ val = strings.TrimPrefix(val, "(")
+ val = strings.TrimSuffix(val, ")")
+ vals := strings.Split(val, ",")
+ if len(vals) < 3 {
+ log.Errorf("vals=%+v", vals)
+ return
+ }
+ rr, err := strconv.ParseInt(vals[0], 10, 32)
+ if err != nil {
+ goto default_value
+ }
+ gg, err := strconv.ParseInt(vals[1], 10, 32)
+ if err != nil {
+ goto default_value
+ }
+ bb, err := strconv.ParseInt(vals[2], 10, 32)
+ if err != nil {
+ goto default_value
+ }
+ r = uint32(rr) * 256
+ g = uint32(gg) * 256
+ b = uint32(bb) * 256
+ } else if strings.HasPrefix(propVal, "#") {
+ hexColor := propVal[1:]
+
+ if len(hexColor) == 3 {
+ rr, err := strconv.ParseInt(hexColor[0:1], 16, 32)
if err != nil {
goto default_value
}
- gg, err := strconv.ParseInt(vals[1], 10, 32)
+ gg, err := strconv.ParseInt(hexColor[1:2], 16, 32)
if err != nil {
goto default_value
}
- bb, err := strconv.ParseInt(vals[2], 10, 32)
+ bb, err := strconv.ParseInt(hexColor[2:3], 16, 32)
if err != nil {
goto default_value
}
- r = uint32(rr) * 256
- g = uint32(gg) * 256
- b = uint32(bb) * 256
- } else if strings.HasPrefix(propVal.Value, "#") {
- hexColor := propVal.Value[1:]
-
- if len(hexColor) == 3 {
- rr, err := strconv.ParseInt(hexColor[0:1], 16, 32)
- if err != nil {
- goto default_value
- }
- gg, err := strconv.ParseInt(hexColor[1:2], 16, 32)
- if err != nil {
- goto default_value
- }
- bb, err := strconv.ParseInt(hexColor[2:3], 16, 32)
- if err != nil {
- goto default_value
- }
- r = uint32(rr) * 256 * 0x11
- g = uint32(gg) * 256 * 0x11
- b = uint32(bb) * 256 * 0x11
- } else if len(hexColor) == 6 {
- rr, err := strconv.ParseInt(hexColor[0:2], 16, 32)
- if err != nil {
- goto default_value
- }
- gg, err := strconv.ParseInt(hexColor[2:4], 16, 32)
- if err != nil {
- goto default_value
- }
- bb, err := strconv.ParseInt(hexColor[4:6], 16, 32)
- if err != nil {
- goto default_value
- }
- r = uint32(rr) * 256
- g = uint32(gg) * 256
- b = uint32(bb) * 256
- } else {
+ r = uint32(rr) * 256 * 0x11
+ g = uint32(gg) * 256 * 0x11
+ b = uint32(bb) * 256 * 0x11
+ } else if len(hexColor) == 6 {
+ rr, err := strconv.ParseInt(hexColor[0:2], 16, 32)
+ if err != nil {
goto default_value
}
- } else if propVal.Value == "inherit" {
- // TODO: handle properly
- goto default_value
- } else {
- colorRGBA, ok := colornames.Map[propVal.Value]
- if !ok {
+ gg, err := strconv.ParseInt(hexColor[2:4], 16, 32)
+ if err != nil {
goto default_value
}
- r, g, b, _ = colorRGBA.RGBA()
+ bb, err := strconv.ParseInt(hexColor[4:6], 16, 32)
+ if err != nil {
+ goto default_value
+ }
+ r = uint32(rr) * 256
+ g = uint32(gg) * 256
+ b = uint32(bb) * 256
+ } else {
+ goto default_value
}
-
- x := (r / 256) << 24
- x = x | ((g / 256) << 16)
- x = x | ((b / 256) << 8)
- x = x | 0x000000ff
-
- return draw.Color(uint32(x)), true
+ } else if propVal == "inherit" {
+ // TODO: handle properly
+ goto default_value
} else {
- return 0, false
+ colorRGBA, ok := colornames.Map[propVal]
+ if !ok {
+ goto default_value
+ }
+ r, g, b, _ = colorRGBA.RGBA()
}
+
+ x = (r / 256) << 24
+ x = x | ((g / 256) << 16)
+ x = x | ((b / 256) << 8)
+ x = x | 0x000000ff
+
+ return draw.Color(uint32(x)), true
default_value:
log.Printf("could not interpret %v", propVal)
return 0, false
--- a/style/stylesheets_test.go
+++ b/style/stylesheets_test.go
@@ -13,27 +13,13 @@
log.Debug = true
}
-func d(c string) Map {
- m := Map{
- Declarations: make(map[string]css.Declaration),
- }
- m.Declarations["color"] = css.Declaration{
- Property: "color",
- Value: c,
- }
- return m
-}
-
func TestColorHex(t *testing.T) {
- tr := d("red")
- hr := d("#ff0000")
-
- tri, ok := tr.colorHex("color")
+ tri, ok := colorHex("red")
if !ok {
t.Fail()
}
- hri, ok := hr.colorHex("color")
+ hri, ok := colorHex("#ff0000")
if !ok {
t.Fail()
}
@@ -41,12 +27,14 @@
if tri != hri {
t.Fatalf("tri=%x hri=%x", tri, hri)
}
+
+ if _, ok := colorHex("rgb(1,2)"); ok {
+ t.Fail()
+ }
}
func TestColorHex3(t *testing.T) {
- m := d("#fff")
-
- c, ok := m.colorHex("color")
+ c, ok := colorHex("#fff")
if !ok {
t.Fail()
}