diff --git a/shared/identicon/block.go b/shared/identicon/block.go deleted file mode 100644 index 46377bd..0000000 --- a/shared/identicon/block.go +++ /dev/null @@ -1,100 +0,0 @@ -package identicon - -import ( - "git.mstar.dev/mstar/canvas" - mathutils "git.mstar.dev/mstar/goutils/math" -) - -type vec2 struct { - X, Y float64 -} - -type block struct { - canvas *canvas.Canvas - blockType int - primary string - secondary string - hash int - pos vec2 - cellSize int - margin int - scale float64 -} - -func (b *block) Offset() { - b.canvas.Save() - b.canvas.Translate(0.6*b.scale, -0.6*b.scale) -} - -func (b *block) ResetOffset() { - b.canvas.Restore() -} - -func (b *block) MakePath(hash int, offset int) { - mod := mathutils.Abs(hash+offset) % 4 - switch mod { - case 0: - // Top - b.canvas.BeginPath() - b.canvas.MoveTo(float64(b.pos.X), float64(b.pos.Y)) - b.canvas.LineTo(b.pos.X+float64(int(b.cellSize)), float64(b.pos.Y)) - b.canvas.LineTo(b.pos.X+float64(int(b.cellSize)), b.pos.Y+float64(int(b.cellSize))) - b.canvas.ClosePath() - case 1: - // Right - b.canvas.BeginPath() - b.canvas.MoveTo(b.pos.X+float64(int(b.cellSize)), float64(b.pos.Y)) - b.canvas.LineTo(b.pos.X+float64(int(b.cellSize)), b.pos.Y+float64(int(b.cellSize))) - b.canvas.LineTo(float64(b.pos.X), b.pos.Y+float64(int(b.cellSize))) - b.canvas.ClosePath() - case 2: - // Bottom - b.canvas.BeginPath() - b.canvas.MoveTo(float64(b.pos.X), float64(b.pos.Y)) - b.canvas.LineTo(float64(b.pos.X), b.pos.Y+float64(int(b.cellSize))) - b.canvas.LineTo(b.pos.X+float64(int(b.cellSize)), b.pos.Y+float64(int(b.cellSize))) - b.canvas.ClosePath() - case 3: - // Left - b.canvas.BeginPath() - b.canvas.MoveTo(float64(b.pos.X), float64(b.pos.Y)) - b.canvas.LineTo(b.pos.X+float64(int(b.cellSize)), float64(b.pos.Y)) - b.canvas.LineTo(float64(b.pos.X), b.pos.Y+float64(int(b.cellSize))) - b.canvas.ClosePath() - default: - // Top - b.canvas.BeginPath() - b.canvas.MoveTo(float64(b.pos.X), float64(b.pos.Y)) - b.canvas.LineTo(b.pos.X+float64(int(b.cellSize)), float64(b.pos.Y)) - b.canvas.LineTo(b.pos.X+float64(int(b.cellSize)), b.pos.Y+float64(int(b.cellSize))) - b.canvas.ClosePath() - } -} - -func (b *block) Draw() { - b.Offset() - switch b.blockType { - case 1: - b.MakePath(b.hash, b.hash%3) - b.canvas.SetFillStyle(b.primary) - b.canvas.Fill() - b.MakePath(b.hash, b.hash%5) - b.canvas.SetFillStyle(b.secondary) - b.canvas.Fill() - case 2: - b.MakePath(b.hash, b.hash%4) - b.canvas.SetFillStyle(b.secondary) - b.canvas.Fill() - b.MakePath(b.hash, b.hash%3) - b.canvas.SetFillStyle(b.primary) - b.canvas.Fill() - default: - b.MakePath(b.hash, b.hash%7) - b.canvas.SetFillStyle(b.secondary) - b.canvas.Fill() - b.MakePath(b.hash, b.hash%8) - b.canvas.SetFillStyle(b.primary) - b.canvas.Fill() - } - b.ResetOffset() -} diff --git a/shared/identicon/identicons.go b/shared/identicon/identicons.go deleted file mode 100644 index 648d212..0000000 --- a/shared/identicon/identicons.go +++ /dev/null @@ -1,219 +0,0 @@ -package identicon - -import ( - "errors" - "fmt" - "image" - "math" - "strings" - - "git.mstar.dev/mstar/canvas" - "git.mstar.dev/mstar/canvas/backend/softwarebackend" - mathutils "git.mstar.dev/mstar/goutils/math" - "git.mstar.dev/mstar/goutils/sliceutils" -) - -type identicon struct { - canvas *canvas.Canvas - primary string - secondary string - margin int - scale float64 - cellSize int - hash int - blocks []block - shape shape - hasStroke bool - strokeWeight int - strokeColor string - compositeOperation string - palette []string -} - -const canvasSize = 500 - -var ( - palette = []string{ - "#F44336", "#E91E63", "#9C27B0", "#673AB7", "#3F51B5", "#2196F3", - "#03A9F4", "#00BCD4", "#009688", "#4CAF50", "#8BC34A", "#CDDC39", - "#FFEB3B", "#FFC107", "#FF9800", "#FF5722", "#795548", "#607D8B", - } - validOperations = []string{ - "source-over", "source-in", "source-out", "source-atop", "destination-over", - "destination-in", "destination-out", "destination-atop", "lighter", "copy", - "xor", "multiply", "screen", "overlay", "darken", "lighten", "color-dodge", - "color-burn", "hard-light", "soft-light", "difference", "exclusion", "hue", - "saturation", "color", "luminosity", - } -) - -// TODO: See if this can be translated to use sr.ht/~sbinet/gg instead -// Deprecated: Doesn't work -func GenerateIdenticon(text string) *image.RGBA { - backend := softwarebackend.New(canvasSize, canvasSize) - canvas := canvas.New(backend) - i := identicon{ - canvas: canvas, - hash: hash(text), - } - i.Init() - i.Draw() - tmp := *backend.Image - return &tmp -} - -func hash(text string) int { - runes := []rune(text) - return sliceutils.Compact( - sliceutils.Map(runes, func(t rune) int { return int(t) }), - func(acc, next int) int { - acc = ((acc << 5) - acc) + next - return acc & acc - }, - ) -} - -func (i *identicon) SetUsername(username string) { - i.hash = hash(username) -} - -func (i *identicon) SetPalette(pal []string) error { - if len(pal) < 2 { - return errors.New("palette to small") - } - i.palette = pal - return nil -} - -func (i *identicon) SetCompositeOperation(newOp string) error { - newOp = strings.ToLower(newOp) - if !sliceutils.Contains(validOperations, newOp) { - return errors.New("invalid operation") - } - i.compositeOperation = newOp - return nil -} - -func (i *identicon) Draw() { - i.Init() - i.canvas.Save() - i.canvas.Translate(float64(canvasSize/2), float64(canvasSize/2)) - i.canvas.Rotate(-math.Pi / 4) - i.canvas.Translate(float64(canvasSize/2), float64(canvasSize/2)) - i.GenerateBlocks() - i.DrawBlocks() - if i.hasStroke { - i.DrawOutline() - } - i.shape = shape{ - canvas: i.canvas, - hash: i.hash, - primary: i.primary, - secondary: i.secondary, - pos: vec2{ - X: float64(i.margin*int(i.scale)) + 1.5*float64(i.cellSize), - Y: float64(i.margin)*i.scale + 0.5*float64(i.cellSize), - }, - scale: i.scale, - cellSize: i.cellSize, - strokeColor: i.strokeColor, - } - i.shape.Draw(i.hasStroke, i.strokeWeight) - i.canvas.Restore() -} - -func (i *identicon) Init() { - i.blocks = []block{} - i.shape = shape{} - i.primary = palette[mathutils.Abs(i.hash%len(palette))] - i.secondary = palette[mathutils.Abs(hash(fmt.Sprint(i.hash))%len(palette))] - // i.canvas.SetGlobalCompositeOperation("source-over") - i.canvas.ClearRect(0, 0, canvasSize, canvasSize) - // i.canvas.SetGlobalCompositeOperation(i.compositeOperation) -} - -func (i *identicon) Offset() { - i.canvas.Save() - i.canvas.Translate(0.6*i.scale, -0.6*i.scale) -} - -func (i *identicon) ResetOffset() { - i.canvas.Restore() -} - -func (i *identicon) GenerateBlocks() { - i.blocks = append(i.blocks, block{ - canvas: i.canvas, - blockType: 1, - primary: i.primary, - secondary: i.secondary, - hash: i.hash, - pos: vec2{float64(i.margin) * i.scale, float64(i.margin) * i.scale}, - cellSize: i.cellSize, - margin: i.margin, - scale: i.scale, - }, block{ - canvas: i.canvas, - blockType: 2, - primary: i.primary, - secondary: i.primary, - hash: i.hash, - pos: vec2{float64(i.margin) * i.scale, float64(i.canvas.Height()) / 2}, - cellSize: i.cellSize, - margin: i.margin, - scale: i.scale, - }, block{ - canvas: i.canvas, - blockType: 3, - primary: i.primary, - secondary: i.secondary, - hash: i.hash, - pos: vec2{float64(i.canvas.Width()) / 2, float64(i.canvas.Height()) / 2}, - cellSize: i.cellSize, - margin: i.margin, - scale: i.scale, - }, - ) -} - -func (i *identicon) DrawOutline() { - i.Offset() - // i.canvas.SetGlobalCompositeOperation("source-over") - i.canvas.BeginPath() - i.canvas.MoveTo(float64(i.margin)*i.scale, float64(i.margin)*i.scale) - i.canvas.LineTo(float64(i.margin)*i.scale, float64(canvasSize)-float64(i.margin)*i.scale) - i.canvas.LineTo( - float64(i.canvas.Width())-float64(i.margin)*i.scale, - float64(i.canvas.Height())-float64(i.margin)*i.scale, - ) - i.canvas.LineTo( - float64(i.canvas.Width())-float64(i.margin)*i.scale, - float64(i.canvas.Height())/2, - ) - i.canvas.LineTo(float64(i.canvas.Width())/2, float64(i.canvas.Height())/2) - i.canvas.LineTo(float64(i.canvas.Width())/2, float64(i.margin)*i.scale) - i.canvas.ClosePath() - - i.canvas.SetStrokeStyle(i.strokeColor) - i.canvas.SetLineWidth(i.scale * (float64(i.strokeWeight) / float64(i.canvas.Width()))) - i.canvas.SetLineJoin(canvas.Round) - i.canvas.SetLineCap(canvas.Round) - i.canvas.Stroke() - - i.canvas.BeginPath() - i.canvas.MoveTo(float64(i.canvas.Width())/2, float64(i.canvas.Height())/2) - i.canvas.LineTo(float64(i.margin)*i.scale, float64(i.canvas.Height())/2) - i.canvas.MoveTo(float64(i.canvas.Width())/2, float64(i.canvas.Height())/2) - i.canvas.LineTo( - float64(i.canvas.Width())/2, - float64(i.canvas.Height())-(float64(i.margin)*i.scale), - ) - i.canvas.Stroke() - i.ResetOffset() -} - -func (i *identicon) DrawBlocks() { - for _, b := range i.blocks { - b.Draw() - } -} diff --git a/shared/identicon/shape.go b/shared/identicon/shape.go deleted file mode 100644 index 4c80c95..0000000 --- a/shared/identicon/shape.go +++ /dev/null @@ -1,112 +0,0 @@ -package identicon - -import ( - "math" - - "git.mstar.dev/mstar/canvas" - mathutils "git.mstar.dev/mstar/goutils/math" -) - -type shape struct { - canvas *canvas.Canvas - hash int - primary string - secondary string - pos vec2 - scale float64 - cellSize int - strokeColor string -} - -func (s *shape) GetColor() string { - if mathutils.Abs(s.hash) == 0 { - return s.primary - } else { - return s.secondary - } -} - -func (s *shape) MakePath() { - mod := mathutils.Abs(s.hash+1) % 4 - switch mod { - case 0: - // square - s.canvas.BeginPath() - s.canvas.MoveTo(float64(s.pos.X), float64(s.pos.Y)) - s.canvas.LineTo(float64(s.pos.X+float64(s.cellSize/2)), float64(s.pos.Y)) - s.canvas.LineTo( - float64(s.pos.X+float64(s.cellSize/2)), - float64(s.pos.Y-float64(s.cellSize/2)), - ) - s.canvas.LineTo(float64(s.pos.X), float64(s.pos.Y-float64(s.cellSize/2))) - s.canvas.ClosePath() - case 1: - // circle - s.canvas.BeginPath() - s.canvas.Arc( - float64(s.pos.X)+float64(s.cellSize)/math.Pi-5, - float64(s.pos.Y)-float64(s.cellSize)/math.Pi+5, - float64(s.cellSize)/3, - 0, - math.Pi*2, - true, - ) - case 2: - // triangle - s.canvas.BeginPath() - s.canvas.MoveTo(float64(s.pos.X), float64(s.pos.Y)) - s.canvas.LineTo(float64(s.pos.X)+float64(s.cellSize)*0.65, float64(s.pos.Y)) - s.canvas.LineTo(float64(s.pos.X), float64(s.pos.Y)-float64(s.cellSize)*0.65) - s.canvas.ClosePath() - case 3: - // oval - s.canvas.BeginPath() - s.canvas.MoveTo( - float64(s.pos.X)-float64(s.cellSize)*0.2, - float64(s.pos.Y)+float64(s.cellSize)*0.2, - ) - s.canvas.QuadraticCurveTo( - float64(s.pos.X)+float64(s.cellSize)*0.4, - float64(s.pos.Y), - float64(s.pos.X)+float64(s.cellSize)*0.5, - float64(s.pos.Y)-float64(s.cellSize)*0.5, - ) - s.canvas.MoveTo( - float64(s.pos.X)+float64(s.cellSize)*0.5, - float64(s.pos.Y)-float64(s.cellSize)*0.5, - ) - s.canvas.QuadraticCurveTo( - float64(s.pos.X), - float64(s.pos.Y)-float64(s.cellSize)*0.4, - float64(s.pos.X)-float64(s.cellSize)*0.2, - float64(s.pos.Y)+float64(s.cellSize)*0.2, - ) - default: - // square - s.canvas.BeginPath() - s.canvas.MoveTo(float64(s.pos.X), float64(s.pos.Y)) - s.canvas.LineTo(float64(s.pos.X+float64(s.cellSize/2)), float64(s.pos.Y)) - s.canvas.LineTo( - float64(s.pos.X+float64(s.cellSize/2)), - float64(s.pos.Y-float64(s.cellSize/2)), - ) - s.canvas.LineTo(float64(s.pos.X), float64(s.pos.Y-float64(s.cellSize/2))) - s.canvas.ClosePath() - } -} - -func (s *shape) Draw(hasStroke bool, strokeWeight int) { - color := s.GetColor() - // THIS SHIT ISN'T IMPLEMENTED! I hope it will work regardless - // s.canvas.SetGlobalCompositeOperation("source-over") - s.MakePath() - s.canvas.SetFillStyle(color) - s.canvas.SetStrokeStyle(s.strokeColor) - s.canvas.SetLineWidth(s.scale * (4 / 5 * float64(strokeWeight)) / float64(canvasSize)) - s.canvas.SetLineJoin(canvas.Round) - s.canvas.SetLineCap(canvas.Round) - s.canvas.Fill() - if hasStroke { - s.canvas.Stroke() - } -}