<commit_before>package font

import (
	"golang.org/x/image/math/fixed"
	"image"
	"image/draw"
	"unicode/utf8"
)

type rgba struct{
	r,g,b,a uint32
}
type signature struct{
	s string
	dy int
	rgba
}
var cache map[signature]*image.RGBA
func init(){
	cache = make(map[signature]*image.RGBA)
}

func StringBG(dst draw.Image, p image.Point, src image.Image, sp image.Point, ft *Font, s []byte, bg image.Image, bgp image.Point) int {
	quad := rgba{}
	{
		r,g,b,a := src.(*image.Uniform).RGBA()
		quad=rgba{r,g,b,a}
	}
	sig := signature{
		s: string(s),
		dy: ft.Dy(),
		rgba: quad,
	}
	if img, ok := cache[sig]; ok{
		draw.Draw(dst, img.Bounds().Add(p), img, img.Bounds().Min, draw.Src)
		return p.X+img.Bounds().Dx() //Add(image.Pt(img.Bounds().Dx(), 0))
	}
	r0 := image.Rectangle{p, p}
	for _, b := range s {
		mask := ft.Char(b)
		if mask == nil {
			panic("StringBG")
		}
		r := mask.Bounds()
		if r0.Min == image.ZP{
			r0.Min = r.Add(p).Min
		}
		draw.DrawMask(dst, r.Add(p), src, sp, mask, mask.Bounds().Min, draw.Over)
		p.X += r.Dx() + ft.stride
		r0.Max.X += r.Dx() + ft.stride
		if r.Dy() > r0.Dy(){
			r0.Max.Y=r.Dy()
		}
	}
	img := image.NewRGBA(image.Rect(0,0,r0.Max.X,r0.Max.Y))
	draw.Draw(img, img.Bounds(), bg, bgp, draw.Src)
	draw.Draw(img, img.Bounds(), dst, r0.Min, draw.Src)
	cache[sig]=img
	return p.X
}

func StringNBG(dst draw.Image, p image.Point, src image.Image, sp image.Point, ft *Font, s []byte) int {
	for _, b := range s {
		mask := ft.Char(b)
		if mask == nil {
			panic("StringBG")
		}
		r := mask.Bounds()
		draw.DrawMask(dst, r.Add(p), src, sp, mask, mask.Bounds().Min, draw.Over)
		p.X += r.Dx() + ft.stride
	}
	return p.X
}

func RuneBG(dst draw.Image, p image.Point, src image.Image, sp image.Point, ft *Font, s []byte, bg image.Image, bgp image.Point) int {
	p.Y += ft.Size()
	for {
		b, size := utf8.DecodeRune(s)<commit_msg>cache every letter with bg color<commit_after>package font

import (
	"golang.org/x/image/math/fixed"
	"image"
	"image/draw"
	"unicode/utf8"
)

type rgba struct{
	r,g,b,a uint32
}
type signature struct{
	b byte
	dy int
	rgba
}
var cache map[signature]*image.RGBA
func init(){
	cache = make(map[signature]*image.RGBA)
}

func StringBG(dst draw.Image, p image.Point, src image.Image, sp image.Point, ft *Font, s []byte, bg image.Image, bgp image.Point) int {
	quad := rgba{}
	{
		r,g,b,a := src.(*image.Uniform).RGBA()
		quad=rgba{r,g,b,a}
	}
	sig := signature{
		dy: ft.Dy(),
		rgba: quad,
	}
	r0 := image.Rectangle{p, p}
	for _, b := range s {
		sig.b = b
		if img, ok := cache[sig]; ok{
			draw.Draw(dst, img.Bounds().Add(p), img, img.Bounds().Min, draw.Src)
			p.X+=img.Bounds().Dx()+ft.stride //Add(image.Pt(img.Bounds().Dx(), 0))
			continue
		}
		mask := ft.Char(b)
		if mask == nil {
			panic("StringBG")
		}
		r := mask.Bounds()
		if r0.Min == image.ZP{
			r0.Min = r.Add(p).Min
		}
		draw.DrawMask(dst, r.Add(p), src, sp, mask, mask.Bounds().Min, draw.Over)
		img := image.NewRGBA(r)
		draw.Draw(img, img.Bounds(), bg, bgp, draw.Src)
		draw.Draw(img, img.Bounds(), dst, r.Add(p).Min, draw.Src)
		cache[sig]=img
		
		p.X += r.Dx() + ft.stride
		r0.Max.X += r.Dx() + ft.stride
		if r.Dy() > r0.Dy(){
			r0.Max.Y=r.Dy()
		}
	}
	return p.X
}

func StringNBG(dst draw.Image, p image.Point, src image.Image, sp image.Point, ft *Font, s []byte) int {
	for _, b := range s {
		mask := ft.Char(b)
		if mask == nil {
			panic("StringBG")
		}
		r := mask.Bounds()
		draw.DrawMask(dst, r.Add(p), src, sp, mask, mask.Bounds().Min, draw.Over)
		p.X += r.Dx() + ft.stride
	}
	return p.X
}

func RuneBG(dst draw.Image, p image.Point, src image.Image, sp image.Point, ft *Font, s []byte, bg image.Image, bgp image.Point) int {
	p.Y += ft.Size()
	for {
		b, size := utf8.DecodeRune(s)
{'fraction_non_alphanumeric': 0.20139260846277451, 'fraction_numerical': 0.00723085163363685, 'mean_word_length': 3.249146757679181, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 5, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4279848', 'n_tokens_mistral': 1721, 'n_tokens_neox': 1622, 'n_words': 376}