shithub: mycel

Download patch

ref: 218bfd840e747fb26788ca58427892332c23d76a
parent: 96375d3675de6ca7e7cc4d3a841d0c6a61cd7d73
author: Philip Silva <philip.silva@protonmail.com>
date: Sat May 1 05:14:24 EDT 2021

Use system font

- from font variable
- use different sized variants as well

--- a/README.md
+++ b/README.md
@@ -52,6 +52,8 @@
 go run . '-quiet=false' '-debug=true'
 ```
 
+`$font` is used to select the font.
+
 ## macOS
 
 Requirements:
--- a/nodes/nodes.go
+++ b/nodes/nodes.go
@@ -4,7 +4,6 @@
 	"bytes"
 	"fmt"
 	"golang.org/x/net/html"
-	"golang.org/x/text/width"
 	"github.com/chris-ramon/douceur/css"
 	"github.com/psilva261/opossum/logger"
 	"github.com/psilva261/opossum/style"
@@ -81,7 +80,7 @@
 // filterText removes line break runes (TODO: add this later but handle properly) and maps runes to canonical widths
 func filterText(t string) string {
 	t = strings.ReplaceAll(t, "­", "")
-	return width.Fold.String(t)
+	return t
 }
 
 func (n Node) Type() html.NodeType {
--- a/nodes/nodes_test.go
+++ b/nodes/nodes_test.go
@@ -17,14 +17,6 @@
 	}
 }
 
-func TestFilterTextFw(t *testing.T) {
-	const s = "(1999)"
-	f := filterText(s)
-	if f != "(1999)" {
-		t.Errorf("%v", f)
-	}
-}
-
 func TestQueryRef(t *testing.T) {
 	buf := strings.NewReader(`
 	<html>
--- a/style/fonts_plan9.go
+++ b/style/fonts_plan9.go
@@ -3,12 +3,94 @@
 package style
 
 import (
+	"9fans.net/go/draw"
 	"fmt"
+	"io/fs"
+	"regexp"
+	"strings"
+	"os"
 )
 
+var (
+	fonts map[int]*draw.Font
+	fontHs []int
+)
+
 func initFontserver() {}
 
-func (cs Map) FontFilename() string {
-	fontSize := matchClosestFontSize(cs.FontSize(), []int{6,7,8,10,13})
-	return fmt.Sprintf("/lib/font/bit/lucidasans/unicode.%v.font", fontSize)
+func initFonts() {
+	fonts = make(map[int]*draw.Font)
+	fontHs = make([]int, 0, 5)
+	if dui == nil {
+		// unit tests
+		return
+	}
+	def := dui.Display.DefaultFont.Name
+	ms, err := fontsLike(def)
+	if err != nil {
+		log.Errorf("find fonts: %v", err)
+	}
+
+	log.Infof("fonts in directory: %+v\n", ms)
+	for _, m := range ms {
+		f, err := dui.Display.OpenFont(m)
+		if err != nil {
+			log.Errorf("open font: %v", err)
+			continue
+		}
+		fonts[f.Height] = f
+		fontHs = append(fontHs, f.Height)
+	}
+	log.Infof("font heights: %+v", fontHs)
+}
+
+var reNum = regexp.MustCompile(`(\d+(x\d+)?)`)
+
+func fontId(fn string) string {
+	return reNum.ReplaceAllString(fn, "")
+}
+
+func fontsLike(path string) (fts []string, err error) {
+	fts = make([]string, 0, 5)
+
+	if path == "*default*" {
+		log.Infof("use default font")
+		path = "/lib/font/bit/lucidasans/unicode.13.font"
+	}
+
+	l := strings.Split(path, "/")
+	dn := strings.Join(l[:len(l)-1], "/")
+	fn := l[len(l)-1]
+	dir := os.DirFS(dn)
+	ms, err := fs.Glob(dir, "*.font")
+	if err != nil {
+		return
+	}
+
+	log.Infof("fonts in directory: %+v\n", ms)
+	for _, m := range ms {
+		if fontId(fn) != fontId(m) {
+			continue
+		}
+		log.Infof("add font %v\n", m)
+		fts = append(fts, dn+"/"+m)
+	}
+
+	if len(fts) == 0 {
+		return nil, fmt.Errorf("unable to find fonts in %v", dn)
+	}
+
+	return
+}
+
+func (cs Map) FontFilename() (fn string, ok bool) {
+	if fonts == nil {
+		initFonts()
+	}
+	h := matchClosestFontSize(2*cs.FontSize(), fontHs)
+	f, ok := fonts[h]
+	if !ok {
+		return
+	}
+	return f.Name, true
 }
--- a/style/fonts_unix.go
+++ b/style/fonts_unix.go
@@ -45,7 +45,7 @@
 	return
 }
 
-func (cs Map) FontFilename() string {
+func (cs Map) FontFilename() (string, bool) {
 	f := cs.preferedFontName([]string{"HelveticaNeue", "Helvetica"})
 	if _, ok := availableFontSizes[f]; !ok {
 		fss, err := fontSizes(f)
@@ -56,5 +56,5 @@
 	}
 	s := matchClosestFontSize(2*cs.FontSize(), availableFontSizes[f])
 
-	return fmt.Sprintf("/mnt/font/"+f+"%va/font", s)
+	return fmt.Sprintf("/mnt/font/"+f+"%va/font", s), true
 }
--- a/style/stylesheets.go
+++ b/style/stylesheets.go
@@ -273,8 +273,8 @@
 }
 
 func (cs Map) Font() *draw.Font {
-	fn := cs.FontFilename()
-	if dui == nil {
+	fn, ok := cs.FontFilename()
+	if !ok || dui == nil {
 		return nil
 	}
 	font, ok := fontCache[fn]