From f73287be870dd9c0a5db157642d85435f731698d Mon Sep 17 00:00:00 2001 From: Admin <2762713521@qq.com> Date: Mon, 5 May 2025 23:27:04 +0800 Subject: [PATCH] all: clean up code, upgrade to modern Go Signed-off-by: ddkwork --- app/gl_macos.go | 1 - app/os_darwin.go | 1 + app/os_x11.go | 5 +- app/window.go | 5 +- f32/affine_test.go | 12 ++-- gpu/clip_test.go | 2 +- gpu/gpu.go | 13 ++-- gpu/headless/driver_test.go | 8 ++- gpu/internal/d3d11/d3d11_windows.go | 11 +-- gpu/internal/driver/driver.go | 8 ++- gpu/internal/opengl/opengl.go | 17 ++--- gpu/internal/rendertest/bench_test.go | 38 +++++----- gpu/internal/rendertest/clip_test.go | 3 +- gpu/internal/rendertest/render_test.go | 7 +- gpu/internal/rendertest/util_test.go | 10 +-- gpu/pack_test.go | 4 +- gpu/path.go | 4 +- internal/byteslice/byteslice.go | 4 +- internal/debug/debug.go | 2 +- internal/egl/egl.go | 8 +-- internal/egl/egl_windows.go | 2 +- internal/f32color/f32colorgen/main.go | 4 +- internal/f32color/rgba_test.go | 6 +- internal/fling/extrapolation.go | 30 ++++---- internal/gl/gl_js.go | 95 +++++++++++++++++++++++++ internal/gl/gl_windows.go | 98 +++++++++++++++++++++++++- internal/ops/ops.go | 10 +-- internal/ops/reader.go | 4 +- internal/stroke/stroke.go | 4 +- internal/stroke/stroke_test.go | 2 +- internal/vk/vulkan.go | 2 +- internal/vk/vulkan_android.go | 1 + internal/vk/vulkan_wayland.go | 1 + internal/vk/vulkan_x11.go | 1 + io/event/event.go | 2 +- io/input/clipboard.go | 7 +- io/input/clipboard_test.go | 2 +- io/input/key.go | 7 +- io/input/pointer.go | 55 +++++---------- io/input/pointer_test.go | 28 +++++--- io/input/router.go | 3 +- io/input/router_test.go | 2 +- io/input/semantic_test.go | 2 +- io/pointer/pointer.go | 3 +- layout/list.go | 4 -- layout/list_test.go | 18 +++-- layout/stack_test.go | 6 +- op/clip/clip.go | 2 +- op/paint/paint.go | 5 +- text/gotext.go | 4 +- text/gotext_test.go | 5 +- text/lru_test.go | 4 +- widget/editor.go | 4 +- widget/editor_test.go | 4 +- widget/fit_test.go | 15 ++-- widget/index_test.go | 39 +++++----- widget/text.go | 2 +- widget/text_bench_test.go | 8 +-- 58 files changed, 413 insertions(+), 241 deletions(-) diff --git a/app/gl_macos.go b/app/gl_macos.go index a0d63e62..2535d9bf 100644 --- a/app/gl_macos.go +++ b/app/gl_macos.go @@ -8,7 +8,6 @@ package app import ( "errors" "runtime" - "unsafe" "gioui.org/gpu" diff --git a/app/os_darwin.go b/app/os_darwin.go index fc5a4353..a7578e3a 100644 --- a/app/os_darwin.go +++ b/app/os_darwin.go @@ -40,6 +40,7 @@ static CFTypeRef newNSString(unichar *chars, NSUInteger length) { } */ import "C" + import ( "errors" "sync" diff --git a/app/os_x11.go b/app/os_x11.go index 83e6b351..24b0ed8e 100644 --- a/app/os_x11.go +++ b/app/os_x11.go @@ -26,6 +26,7 @@ package app */ import "C" + import ( "errors" "fmt" @@ -751,9 +752,7 @@ func (h *x11EventHandler) handleEvents() bool { return redraw } -var ( - x11Threads sync.Once -) +var x11Threads sync.Once func init() { x11Driver = newX11Window diff --git a/app/window.go b/app/window.go index bebd7e18..3953600d 100644 --- a/app/window.go +++ b/app/window.go @@ -444,10 +444,7 @@ func (c *callbacks) SetComposingRegion(r key.Range) { func (c *callbacks) EditorInsert(text string) { sel := c.w.imeState.Selection.Range c.EditorReplace(sel, text) - start := sel.Start - if sel.End < start { - start = sel.End - } + start := min(sel.End, sel.Start) sel.Start = start + utf8.RuneCountInString(text) sel.End = sel.Start c.SetEditorSelection(sel) diff --git a/f32/affine_test.go b/f32/affine_test.go index 42c739f6..b572d237 100644 --- a/f32/affine_test.go +++ b/f32/affine_test.go @@ -201,7 +201,7 @@ func BenchmarkTransformOffset(b *testing.B) { o := Point{X: 0.5, Y: 0.5} aff := Affine2D{}.Offset(o) - for i := 0; i < b.N; i++ { + for b.Loop() { p = aff.Transform(p) } _ = p @@ -211,7 +211,7 @@ func BenchmarkTransformScale(b *testing.B) { p := Point{X: 1, Y: 2} s := Point{X: 0.5, Y: 0.5} aff := Affine2D{}.Scale(Point{}, s) - for i := 0; i < b.N; i++ { + for b.Loop() { p = aff.Transform(p) } _ = p @@ -221,7 +221,7 @@ func BenchmarkTransformRotate(b *testing.B) { p := Point{X: 1, Y: 2} a := float32(math.Pi / 2) aff := Affine2D{}.Rotate(Point{}, a) - for i := 0; i < b.N; i++ { + for b.Loop() { p = aff.Transform(p) } _ = p @@ -231,7 +231,7 @@ func BenchmarkTransformTranslateMultiply(b *testing.B) { a := Affine2D{}.Offset(Point{X: 1, Y: 1}).Rotate(Point{}, math.Pi/3) t := Affine2D{}.Offset(Point{X: 0.5, Y: 0.5}) - for i := 0; i < b.N; i++ { + for b.Loop() { a = a.Mul(t) } } @@ -240,7 +240,7 @@ func BenchmarkTransformScaleMultiply(b *testing.B) { a := Affine2D{}.Offset(Point{X: 1, Y: 1}).Rotate(Point{}, math.Pi/3) t := Affine2D{}.Offset(Point{X: 0.5, Y: 0.5}).Scale(Point{}, Point{X: 0.4, Y: -0.5}) - for i := 0; i < b.N; i++ { + for b.Loop() { a = a.Mul(t) } } @@ -249,7 +249,7 @@ func BenchmarkTransformMultiply(b *testing.B) { a := Affine2D{}.Offset(Point{X: 1, Y: 1}).Rotate(Point{}, math.Pi/3) t := Affine2D{}.Offset(Point{X: 0.5, Y: 0.5}).Rotate(Point{}, math.Pi/7) - for i := 0; i < b.N; i++ { + for b.Loop() { a = a.Mul(t) } } diff --git a/gpu/clip_test.go b/gpu/clip_test.go index ef4ddbe2..a1d1256a 100644 --- a/gpu/clip_test.go +++ b/gpu/clip_test.go @@ -10,7 +10,7 @@ import ( func BenchmarkEncodeQuadTo(b *testing.B) { var data [vertStride * 4]byte - for i := 0; i < b.N; i++ { + for i := 0; b.Loop(); i++ { v := float32(i) encodeQuadTo(data[:], 123, f32.Point{X: v, Y: v}, diff --git a/gpu/gpu.go b/gpu/gpu.go index 49c878ea..3ea528af 100644 --- a/gpu/gpu.go +++ b/gpu/gpu.go @@ -15,6 +15,7 @@ import ( "image/color" "math" "reflect" + "slices" "time" "unsafe" @@ -189,7 +190,7 @@ const ( // imageOpData is the shadow of paint.ImageOp. type imageOpData struct { src *image.RGBA - handle interface{} + handle any filter byte } @@ -200,7 +201,7 @@ type linearGradientOpData struct { color2 color.NRGBA } -func decodeImageOp(data []byte, refs []interface{}) imageOpData { +func decodeImageOp(data []byte, refs []any) imageOpData { handle := refs[1] if handle == nil { return imageOpData{} @@ -547,7 +548,7 @@ func newBlitter(ctx driver.Device) *blitter { b.texUniforms = new(blitTexUniforms) b.linearGradientUniforms = new(blitLinearGradientUniforms) pipelines, err := createColorPrograms(ctx, gio.Shader_blit_vert, gio.Shader_blit_frag, - [3]interface{}{b.colUniforms, b.linearGradientUniforms, b.texUniforms}, + [3]any{b.colUniforms, b.linearGradientUniforms, b.texUniforms}, ) if err != nil { panic(err) @@ -565,7 +566,7 @@ func (b *blitter) release() { } } -func createColorPrograms(b driver.Device, vsSrc shader.Sources, fsSrc [3]shader.Sources, uniforms [3]interface{}) (pipelines [2][3]*pipeline, err error) { +func createColorPrograms(b driver.Device, vsSrc shader.Sources, fsSrc [3]shader.Sources, uniforms [3]any) (pipelines [2][3]*pipeline, err error) { defer func() { if err != nil { for _, p := range pipelines { @@ -822,7 +823,7 @@ func (r *renderer) packLayers(layers []opacityLayer) []opacityLayer { layers[l.parent].clip = b.Union(l.clip) } if l.clip.Empty() { - layers = append(layers[:i], layers[i+1:]...) + layers = slices.Delete(layers, i, i+1) } } // Pack layers. @@ -1316,7 +1317,7 @@ func (b *blitter) blit(mat materialType, fbo bool, col f32color.RGBA, col1, col2 // newUniformBuffer creates a new GPU uniform buffer backed by the // structure uniformBlock points to. -func newUniformBuffer(b driver.Device, uniformBlock interface{}) *uniformBuffer { +func newUniformBuffer(b driver.Device, uniformBlock any) *uniformBuffer { ref := reflect.ValueOf(uniformBlock) // Determine the size of the uniforms structure, *uniforms. size := ref.Elem().Type().Size() diff --git a/gpu/headless/driver_test.go b/gpu/headless/driver_test.go index 2120152c..a772c3bd 100644 --- a/gpu/headless/driver_test.go +++ b/gpu/headless/driver_test.go @@ -21,8 +21,10 @@ import ( var dumpImages = flag.Bool("saveimages", false, "save test images") -var clearCol = color.NRGBA{A: 0xff, R: 0xde, G: 0xad, B: 0xbe} -var clearColExpect = f32color.NRGBAToRGBA(clearCol) +var ( + clearCol = color.NRGBA{A: 0xff, R: 0xde, G: 0xad, B: 0xbe} + clearColExpect = f32color.NRGBAToRGBA(clearCol) +) func TestFramebufferClear(t *testing.T) { b := newDriver(t) @@ -202,5 +204,5 @@ func saveImage(file string, img image.Image) error { if err := png.Encode(&buf, img); err != nil { return err } - return os.WriteFile(file, buf.Bytes(), 0666) + return os.WriteFile(file, buf.Bytes(), 0o666) } diff --git a/gpu/internal/d3d11/d3d11_windows.go b/gpu/internal/d3d11/d3d11_windows.go index b737f2cc..f27eda75 100644 --- a/gpu/internal/d3d11/d3d11_windows.go +++ b/gpu/internal/d3d11/d3d11_windows.go @@ -152,9 +152,7 @@ func newDirect3D11Device(api driver.Direct3D11) (driver.Device, error) { } func (b *Backend) BeginFrame(target driver.RenderTarget, clear bool, viewport image.Point) driver.Texture { - var ( - renderTarget *d3d11.RenderTargetView - ) + var renderTarget *d3d11.RenderTargetView if target != nil { switch t := target.(type) { case driver.Direct3D11RenderTarget: @@ -229,10 +227,7 @@ func (b *Backend) NewTexture(format driver.TextureFormat, width, height int, min // Flags required by ID3D11DeviceContext::GenerateMips. bindFlags |= d3d11.BIND_SHADER_RESOURCE | d3d11.BIND_RENDER_TARGET miscFlags |= d3d11.RESOURCE_MISC_GENERATE_MIPS - dim := width - if height > dim { - dim = height - } + dim := max(height, width) log2 := 32 - bits.LeadingZeros32(uint32(dim)) - 1 nmipmaps = log2 + 1 } @@ -802,7 +797,7 @@ func (t *Texture) ReadPixels(src image.Rectangle, pixels []byte, stride int) err mapSize := dstPitch * h data := sliceOf(resMap.PData, mapSize) width := w * 4 - for r := 0; r < h; r++ { + for r := range h { pixels := pixels[r*srcPitch:] copy(pixels[:width], data[r*dstPitch:]) } diff --git a/gpu/internal/driver/driver.go b/gpu/internal/driver/driver.go index d0e412c9..04865ea4 100644 --- a/gpu/internal/driver/driver.go +++ b/gpu/internal/driver/driver.go @@ -96,8 +96,10 @@ type BlendFactor uint8 type Topology uint8 -type TextureFilter uint8 -type TextureFormat uint8 +type ( + TextureFilter uint8 + TextureFormat uint8 +) type BufferBinding uint8 @@ -217,7 +219,7 @@ func flipImageY(stride, height int, pixels []byte) { // Flip image in y-direction. OpenGL's origin is in the lower // left corner. row := make([]uint8, stride) - for y := 0; y < height/2; y++ { + for y := range height / 2 { y1 := height - y - 1 dest := y1 * stride src := y * stride diff --git a/gpu/internal/opengl/opengl.go b/gpu/internal/opengl/opengl.go index 889a464e..67942b60 100644 --- a/gpu/internal/opengl/opengl.go +++ b/gpu/internal/opengl/opengl.go @@ -8,6 +8,7 @@ import ( "image" "math/bits" "runtime" + "slices" "strings" "time" "unsafe" @@ -717,10 +718,7 @@ func (b *Backend) NewTexture(format driver.TextureFormat, width, height int, min if mipmap { nmipmaps := 1 if mipmap { - dim := width - if height > dim { - dim = height - } + dim := max(height, width) log2 := 32 - bits.LeadingZeros32(uint32(dim)) - 1 nmipmaps = log2 + 1 } @@ -1132,7 +1130,7 @@ func (b *Backend) setupVertexArrays() { enabled[inp.Location] = true b.glstate.vertexAttribPointer(b.funcs, buf.obj, inp.Location, l.Size, gltyp, false, p.layout.Stride, buf.offset+l.Offset) } - for i := 0; i < max; i++ { + for i := range max { b.glstate.setVertexAttribArray(b.funcs, i, enabled[i]) } } @@ -1175,7 +1173,7 @@ func (t *texture) ReadPixels(src image.Rectangle, pixels []byte, stride int) err } else { tmp := make([]byte, w*h*4) t.backend.funcs.ReadPixels(src.Min.X, src.Min.Y, w, h, gl.RGBA, gl.UNSIGNED_BYTE, tmp) - for y := 0; y < h; y++ { + for y := range h { copy(pixels[y*stride:], tmp[y*w*4:]) } } @@ -1357,12 +1355,7 @@ func alphaTripleFor(ver [2]int) textureTriple { } func hasExtension(exts []string, ext string) bool { - for _, e := range exts { - if ext == e { - return true - } - } - return false + return slices.Contains(exts, ext) } func firstBufferType(typ driver.BufferBinding) gl.Enum { diff --git a/gpu/internal/rendertest/bench_test.go b/gpu/internal/rendertest/bench_test.go index 7baece05..f54732ca 100644 --- a/gpu/internal/rendertest/bench_test.go +++ b/gpu/internal/rendertest/bench_test.go @@ -66,8 +66,8 @@ func BenchmarkDrawUICached(b *testing.B) { defer w.Release() drawCore(gtx, th) w.Frame(gtx.Ops) - b.ResetTimer() - for i := 0; i < b.N; i++ { + + for b.Loop() { w.Frame(gtx.Ops) } finishBenchmark(b, w) @@ -83,8 +83,8 @@ func BenchmarkDrawUI(b *testing.B) { drawCore(gtx, th) w.Frame(gtx.Ops) b.ReportAllocs() - b.ResetTimer() - for i := 0; i < b.N; i++ { + + for i := 0; b.Loop(); i++ { resetOps(gtx) off := float32(math.Mod(float64(i)/10, 10)) @@ -105,8 +105,8 @@ func BenchmarkDrawUITransformed(b *testing.B) { drawCore(gtx, th) w.Frame(gtx.Ops) b.ReportAllocs() - b.ResetTimer() - for i := 0; i < b.N; i++ { + + for i := 0; b.Loop(); i++ { resetOps(gtx) angle := float32(math.Mod(float64(i)/1000, 0.05)) @@ -130,8 +130,8 @@ func Benchmark1000Circles(b *testing.B) { draw1000Circles(gtx) w.Frame(gtx.Ops) b.ReportAllocs() - b.ResetTimer() - for i := 0; i < b.N; i++ { + + for b.Loop() { resetOps(gtx) draw1000Circles(gtx) w.Frame(gtx.Ops) @@ -147,8 +147,8 @@ func Benchmark1000CirclesInstanced(b *testing.B) { draw1000CirclesInstanced(gtx) w.Frame(gtx.Ops) b.ReportAllocs() - b.ResetTimer() - for i := 0; i < b.N; i++ { + + for b.Loop() { resetOps(gtx) draw1000CirclesInstanced(gtx) w.Frame(gtx.Ops) @@ -158,9 +158,9 @@ func Benchmark1000CirclesInstanced(b *testing.B) { func draw1000Circles(gtx layout.Context) { ops := gtx.Ops - for x := 0; x < 100; x++ { + for x := range 100 { op.Offset(image.Pt(x*10, 0)).Add(ops) - for y := 0; y < 10; y++ { + for y := range 10 { paint.FillShape(ops, color.NRGBA{R: 100 + uint8(x), G: 100 + uint8(y), B: 100, A: 120}, clip.RRect{Rect: image.Rect(0, 0, 10, 10), NE: 5, SE: 5, SW: 5, NW: 5}.Op(ops), @@ -179,9 +179,9 @@ func draw1000CirclesInstanced(gtx layout.Context) { cl.Pop() c := r.Stop() - for x := 0; x < 100; x++ { + for x := range 100 { op.Offset(image.Pt(x*10, 0)).Add(ops) - for y := 0; y < 10; y++ { + for y := range 10 { paint.ColorOp{Color: color.NRGBA{R: 100 + uint8(x), G: 100 + uint8(y), B: 100, A: 120}}.Add(ops) c.Add(ops) op.Offset(image.Pt(0, 100)).Add(ops) @@ -204,9 +204,9 @@ func drawIndividualShapes(gtx layout.Context, th *material.Theme) chan op.CallOp go func() { ops := &op1 c := op.Record(ops) - for x := 0; x < 9; x++ { + for x := range 9 { op.Offset(image.Pt(x*50, 0)).Add(ops) - for y := 0; y < 9; y++ { + for y := range 9 { paint.FillShape(ops, color.NRGBA{R: 100 + uint8(x), G: 100 + uint8(y), B: 100, A: 120}, clip.RRect{Rect: image.Rect(0, 0, 25, 25), NE: 10, SE: 10, SW: 10, NW: 10}.Op(ops), @@ -233,8 +233,8 @@ func drawShapeInstances(gtx layout.Context, th *material.Theme) chan op.CallOp { squares.Add(ops) rad := float32(0) - for x := 0; x < 20; x++ { - for y := 0; y < 20; y++ { + for x := range 20 { + for y := range 20 { t := op.Offset(image.Pt(x*50+25, y*50+25)).Push(ops) c.Add(ops) t.Pop() @@ -253,7 +253,7 @@ func drawText(gtx layout.Context, th *material.Theme) chan op.CallOp { c := op.Record(ops) txt := material.H6(th, "") - for x := 0; x < 40; x++ { + for x := range 40 { txt.Text = textRows[x] t := op.Offset(image.Pt(0, 24*x)).Push(ops) gtx.Ops = ops diff --git a/gpu/internal/rendertest/clip_test.go b/gpu/internal/rendertest/clip_test.go index 53306f5e..37701e19 100644 --- a/gpu/internal/rendertest/clip_test.go +++ b/gpu/internal/rendertest/clip_test.go @@ -176,7 +176,6 @@ func TestStrokedPathZeroWidth(t *testing.T) { paint.Fill(o, red) cl.Pop() } - }, func(r result) { r.expect(0, 0, transparent) r.expect(10, 50, colornames.Black) @@ -299,7 +298,7 @@ func TestInstancedRects(t *testing.T) { clip.Pop() c := macro.Stop() - for i := 0; i < 2; i++ { + for range 2 { op.Affine(f32.Affine2D{}.Rotate(f32.Pt(0, 0), .2)).Add(o) c.Add(o) op.Offset(image.Pt(20, 20)).Add(o) diff --git a/gpu/internal/rendertest/render_test.go b/gpu/internal/rendertest/render_test.go index 35d025bc..4c60f658 100644 --- a/gpu/internal/rendertest/render_test.go +++ b/gpu/internal/rendertest/render_test.go @@ -24,7 +24,6 @@ func TestTransformMacro(t *testing.T) { c := constSqPath() run(t, func(o *op.Ops) { - // render the first Stacked item m1 := op.Record(o) dr := image.Rect(0, 0, 128, 50) @@ -142,8 +141,10 @@ func constSqPath() clip.Op { func constSqCirc() clip.Op { innerOps := new(op.Ops) - return clip.RRect{Rect: image.Rect(0, 0, 40, 40), - NW: 20, NE: 20, SW: 20, SE: 20}.Op(innerOps) + return clip.RRect{ + Rect: image.Rect(0, 0, 40, 40), + NW: 20, NE: 20, SW: 20, SE: 20, + }.Op(innerOps) } func drawChild(ops *op.Ops, text clip.Op) op.CallOp { diff --git a/gpu/internal/rendertest/util_test.go b/gpu/internal/rendertest/util_test.go index c20e6b3d..a1388163 100644 --- a/gpu/internal/rendertest/util_test.go +++ b/gpu/internal/rendertest/util_test.go @@ -49,8 +49,8 @@ func buildSquares(size int) paint.ImageOp { sub := size / 4 im := image.NewNRGBA(image.Rect(0, 0, size, size)) c1, c2 := image.NewUniform(colornames.Green), image.NewUniform(colornames.Blue) - for r := 0; r < 4; r++ { - for c := 0; c < 4; c++ { + for r := range 4 { + for c := range 4 { c1, c2 = c2, c1 draw.Draw(im, image.Rect(r*sub, c*sub, r*sub+sub, c*sub+sub), c1, image.Point{}, draw.Over) } @@ -78,7 +78,7 @@ func run(t *testing.T, f func(o *op.Ops), c func(r result)) { var img *image.RGBA var err error ops := new(op.Ops) - for i := 0; i < 3; i++ { + for i := range 3 { ops.Reset() img, err = drawImage(t, 128, ops, f) if err != nil { @@ -153,7 +153,7 @@ func verifyRef(t *testing.T, img *image.RGBA, frame int) (ok bool) { } path = filepath.Join("refs", path+".png") if *dumpImages { - if err := os.MkdirAll(filepath.Dir(path), 0766); err != nil { + if err := os.MkdirAll(filepath.Dir(path), 0o766); err != nil { if !os.IsExist(err) { t.Error(err) return @@ -287,7 +287,7 @@ func saveImage(t testing.TB, file string, img *image.RGBA) { t.Error(err) return } - if err := os.WriteFile(file, buf.Bytes(), 0666); err != nil { + if err := os.WriteFile(file, buf.Bytes(), 0o666); err != nil { t.Error(err) return } diff --git a/gpu/pack_test.go b/gpu/pack_test.go index 98db6eb5..e0db75cd 100644 --- a/gpu/pack_test.go +++ b/gpu/pack_test.go @@ -10,10 +10,10 @@ import ( func BenchmarkPacker(b *testing.B) { var p packer p.maxDims = image.Point{X: 4096, Y: 4096} - for i := 0; i < b.N; i++ { + for i := 0; b.Loop(); i++ { p.clear() p.newPage() - for k := 0; k < 500; k++ { + for k := range 500 { _, ok := p.tryAdd(xy(k)) if !ok { b.Fatal("add failed", i, k, xy(k)) diff --git a/gpu/path.go b/gpu/path.go index eb8489b5..f33277ca 100644 --- a/gpu/path.go +++ b/gpu/path.go @@ -150,7 +150,7 @@ func newCoverer(ctx driver.Device) *coverer { c.texUniforms = new(coverTexUniforms) c.linearGradientUniforms = new(coverLinearGradientUniforms) pipelines, err := createColorPrograms(ctx, gio.Shader_cover_vert, gio.Shader_cover_frag, - [3]interface{}{c.colUniforms, c.linearGradientUniforms, c.texUniforms}, + [3]any{c.colUniforms, c.linearGradientUniforms, c.texUniforms}, ) if err != nil { panic(err) @@ -162,7 +162,7 @@ func newCoverer(ctx driver.Device) *coverer { func newStenciler(ctx driver.Device) *stenciler { // Allocate a suitably large index buffer for drawing paths. indices := make([]uint16, pathBatchSize*6) - for i := 0; i < pathBatchSize; i++ { + for i := range pathBatchSize { i := uint16(i) indices[i*6+0] = i*4 + 0 indices[i*6+1] = i*4 + 1 diff --git a/internal/byteslice/byteslice.go b/internal/byteslice/byteslice.go index e84ed90b..5bff4e38 100644 --- a/internal/byteslice/byteslice.go +++ b/internal/byteslice/byteslice.go @@ -10,7 +10,7 @@ import ( ) // Struct returns a byte slice view of a struct. -func Struct(s interface{}) []byte { +func Struct(s any) []byte { v := reflect.ValueOf(s) sz := int(v.Elem().Type().Size()) return unsafe.Slice((*byte)(unsafe.Pointer(v.Pointer())), sz) @@ -27,7 +27,7 @@ func Uint32(s []uint32) []byte { } // Slice returns a byte slice view of a slice. -func Slice(s interface{}) []byte { +func Slice(s any) []byte { v := reflect.ValueOf(s) first := v.Index(0) sz := int(first.Type().Size()) diff --git a/internal/debug/debug.go b/internal/debug/debug.go index f6939332..95cbde75 100644 --- a/internal/debug/debug.go +++ b/internal/debug/debug.go @@ -34,7 +34,7 @@ func Parse() { } print := false silent := false - for _, part := range strings.Split(val, ",") { + for part := range strings.SplitSeq(val, ",") { switch part { case textSubsystem: Text.Store(true) diff --git a/internal/egl/egl.go b/internal/egl/egl.go index ab2eab76..2e323eb7 100644 --- a/internal/egl/egl.go +++ b/internal/egl/egl.go @@ -9,6 +9,7 @@ import ( "errors" "fmt" "runtime" + "slices" "strings" "gioui.org/gpu" @@ -154,12 +155,7 @@ func (c *Context) EnableVSync(enable bool) { } func hasExtension(exts []string, ext string) bool { - for _, e := range exts { - if ext == e { - return true - } - } - return false + return slices.Contains(exts, ext) } func createContext(disp _EGLDisplay) (*eglContext, error) { diff --git a/internal/egl/egl_windows.go b/internal/egl/egl_windows.go index 284f765e..f3cb5292 100644 --- a/internal/egl/egl_windows.go +++ b/internal/egl/egl_windows.go @@ -186,6 +186,6 @@ func eglWaitClient() bool { // issue34474KeepAlive calls runtime.KeepAlive as a // workaround for golang.org/issue/34474. -func issue34474KeepAlive(v interface{}) { +func issue34474KeepAlive(v any) { runtime.KeepAlive(v) } diff --git a/internal/f32color/f32colorgen/main.go b/internal/f32color/f32colorgen/main.go index 3e157250..9407d883 100644 --- a/internal/f32color/f32colorgen/main.go +++ b/internal/f32color/f32colorgen/main.go @@ -16,7 +16,7 @@ func main() { flag.Parse() var b bytes.Buffer - printf := func(content string, args ...interface{}) { + printf := func(content string, args ...any) { fmt.Fprintf(&b, content, args...) } @@ -42,7 +42,7 @@ func main() { panic(err) } - err = os.WriteFile(*out, data, 0755) + err = os.WriteFile(*out, data, 0o755) if err != nil { panic(err) } diff --git a/internal/f32color/rgba_test.go b/internal/f32color/rgba_test.go index eb255d00..3658a099 100644 --- a/internal/f32color/rgba_test.go +++ b/internal/f32color/rgba_test.go @@ -41,17 +41,17 @@ var sink RGBA func BenchmarkLinearFromSRGB(b *testing.B) { b.Run("opaque", func(b *testing.B) { - for i := 0; i < b.N; i++ { + for i := 0; b.Loop(); i++ { sink = LinearFromSRGB(color.NRGBA{R: byte(i), G: byte(i >> 8), B: byte(i >> 16), A: 0xFF}) } }) b.Run("translucent", func(b *testing.B) { - for i := 0; i < b.N; i++ { + for i := 0; b.Loop(); i++ { sink = LinearFromSRGB(color.NRGBA{R: byte(i), G: byte(i >> 8), B: byte(i >> 16), A: 0x50}) } }) b.Run("transparent", func(b *testing.B) { - for i := 0; i < b.N; i++ { + for i := 0; b.Loop(); i++ { sink = LinearFromSRGB(color.NRGBA{R: byte(i), G: byte(i >> 8), B: byte(i >> 16), A: 0x00}) } }) diff --git a/internal/fling/extrapolation.go b/internal/fling/extrapolation.go index 655ef84d..d8e29963 100644 --- a/internal/fling/extrapolation.go +++ b/internal/fling/extrapolation.go @@ -90,7 +90,7 @@ func (e *Extrapolation) Estimate() Estimate { first := e.get(0) t := first.t // Walk backwards collecting samples. - for i := 0; i < len(e.samples); i++ { + for i := range e.samples { p := e.get(-i) age := first.t - p.t if age >= maxAge || t-p.t >= maxSampleGap { @@ -172,9 +172,9 @@ func decomposeQR(A *matrix) (*matrix, *matrix, bool) { // https://en.wikipedia.org/wiki/Gram%E2%80%93Schmidt_process Q := newMatrix(A.rows, A.cols) // Column-major. Rt := newMatrix(A.rows, A.rows) // R transposed, row-major. - for i := 0; i < Q.rows; i++ { + for i := range Q.rows { // Copy A column. - for j := 0; j < Q.cols; j++ { + for j := range Q.cols { Q.set(i, j, A.get(i, j)) } // Subtract projections. Note that int the projection @@ -184,9 +184,9 @@ func decomposeQR(A *matrix) (*matrix, *matrix, bool) { // the normalized column e replaces u, where = 1: // // proje a = / e = e - for j := 0; j < i; j++ { + for j := range i { d := dot(Q.col(j), Q.col(i)) - for k := 0; k < Q.cols; k++ { + for k := range Q.cols { Q.set(i, k, Q.get(i, k)-d*Q.get(j, k)) } } @@ -197,7 +197,7 @@ func decomposeQR(A *matrix) (*matrix, *matrix, bool) { return nil, nil, false } invNorm := 1 / n - for j := 0; j < Q.cols; j++ { + for j := range Q.cols { Q.set(i, j, Q.get(i, j)*invNorm) } // Update Rt. @@ -261,8 +261,8 @@ func (m *matrix) approxEqual(m2 *matrix) bool { return false } const epsilon = 0.00001 - for row := 0; row < m.rows; row++ { - for col := 0; col < m.cols; col++ { + for row := range m.rows { + for col := range m.cols { d := m2.get(row, col) - m.get(row, col) if d < -epsilon || d > epsilon { return false @@ -278,8 +278,8 @@ func (m *matrix) transpose() *matrix { cols: m.rows, data: make([]float32, len(m.data)), } - for i := 0; i < m.rows; i++ { - for j := 0; j < m.cols; j++ { + for i := range m.rows { + for j := range m.cols { t.set(j, i, m.get(i, j)) } } @@ -295,10 +295,10 @@ func (m *matrix) mul(m2 *matrix) *matrix { cols: m2.cols, data: make([]float32, m.rows*m2.cols), } - for i := 0; i < mm.rows; i++ { - for j := 0; j < mm.cols; j++ { + for i := range mm.rows { + for j := range mm.cols { var v float32 - for k := 0; k < m.rows; k++ { + for k := range m.rows { v += m.get(k, j) * m2.get(i, k) } mm.set(i, j, v) @@ -309,8 +309,8 @@ func (m *matrix) mul(m2 *matrix) *matrix { func (m *matrix) String() string { var b strings.Builder - for i := 0; i < m.rows; i++ { - for j := 0; j < m.cols; j++ { + for i := range m.rows { + for j := range m.cols { v := m.get(i, j) b.WriteString(strconv.FormatFloat(float64(v), 'g', -1, 32)) b.WriteString(", ") diff --git a/internal/gl/gl_js.go b/internal/gl/gl_js.go index a85daf90..f2d794aa 100644 --- a/internal/gl/gl_js.go +++ b/internal/gl/gl_js.go @@ -247,9 +247,11 @@ func (f *Functions) getExtension(name string) js.Value { func (f *Functions) ActiveTexture(t Enum) { f._activeTexture.Invoke(int(t)) } + func (f *Functions) AttachShader(p Program, s Shader) { f._attachShader.Invoke(js.Value(p), js.Value(s)) } + func (f *Functions) BeginQuery(target Enum, query Query) { if !f.EXT_disjoint_timer_query_webgl2.IsNull() { f._beginQuery.Invoke(int(target), js.Value(query)) @@ -257,36 +259,47 @@ func (f *Functions) BeginQuery(target Enum, query Query) { f.EXT_disjoint_timer_query.Call("beginQueryEXT", int(target), js.Value(query)) } } + func (f *Functions) BindAttribLocation(p Program, a Attrib, name string) { f._bindAttribLocation.Invoke(js.Value(p), int(a), name) } + func (f *Functions) BindBuffer(target Enum, b Buffer) { f._bindBuffer.Invoke(int(target), js.Value(b)) } + func (f *Functions) BindBufferBase(target Enum, index int, b Buffer) { f._bindBufferBase.Invoke(int(target), index, js.Value(b)) } + func (f *Functions) BindFramebuffer(target Enum, fb Framebuffer) { f._bindFramebuffer.Invoke(int(target), js.Value(fb)) } + func (f *Functions) BindRenderbuffer(target Enum, rb Renderbuffer) { f._bindRenderbuffer.Invoke(int(target), js.Value(rb)) } + func (f *Functions) BindTexture(target Enum, t Texture) { f._bindTexture.Invoke(int(target), js.Value(t)) } + func (f *Functions) BindImageTexture(unit int, t Texture, level int, layered bool, layer int, access, format Enum) { panic("not implemented") } + func (f *Functions) BindVertexArray(a VertexArray) { panic("not supported") } + func (f *Functions) BlendEquation(mode Enum) { f._blendEquation.Invoke(int(mode)) } + func (f *Functions) BlendFuncSeparate(srcRGB, dstRGB, srcA, dstA Enum) { f._blendFunc.Invoke(int(srcRGB), int(dstRGB), int(srcA), int(dstA)) } + func (f *Functions) BufferData(target Enum, size int, usage Enum, data []byte) { if data == nil { f._bufferData.Invoke(int(target), size, int(usage)) @@ -297,9 +310,11 @@ func (f *Functions) BufferData(target Enum, size int, usage Enum, data []byte) { f._bufferData.Invoke(int(target), f.byteArrayOf(data), int(usage)) } } + func (f *Functions) BufferSubData(target Enum, offset int, src []byte) { f._bufferSubData.Invoke(int(target), offset, f.byteArrayOf(src)) } + func (f *Functions) CheckFramebufferStatus(target Enum) Enum { status := Enum(f._checkFramebufferStatus.Invoke(int(target)).Int()) if status != FRAMEBUFFER_COMPLETE && f.Ctx.Call("isContextLost").Bool() { @@ -308,54 +323,71 @@ func (f *Functions) CheckFramebufferStatus(target Enum) Enum { } return status } + func (f *Functions) Clear(mask Enum) { f._clear.Invoke(int(mask)) } + func (f *Functions) ClearColor(red, green, blue, alpha float32) { f._clearColor.Invoke(red, green, blue, alpha) } + func (f *Functions) ClearDepthf(d float32) { f._clearDepth.Invoke(d) } + func (f *Functions) CompileShader(s Shader) { f._compileShader.Invoke(js.Value(s)) } + func (f *Functions) CopyTexSubImage2D(target Enum, level, xoffset, yoffset, x, y, width, height int) { f._copyTexSubImage2D.Invoke(int(target), level, xoffset, yoffset, x, y, width, height) } + func (f *Functions) CreateBuffer() Buffer { return Buffer(f._createBuffer.Invoke()) } + func (f *Functions) CreateFramebuffer() Framebuffer { return Framebuffer(f._createFramebuffer.Invoke()) } + func (f *Functions) CreateProgram() Program { return Program(f._createProgram.Invoke()) } + func (f *Functions) CreateQuery() Query { return Query(f._createQuery.Invoke()) } + func (f *Functions) CreateRenderbuffer() Renderbuffer { return Renderbuffer(f._createRenderbuffer.Invoke()) } + func (f *Functions) CreateShader(ty Enum) Shader { return Shader(f._createShader.Invoke(int(ty))) } + func (f *Functions) CreateTexture() Texture { return Texture(f._createTexture.Invoke()) } + func (f *Functions) CreateVertexArray() VertexArray { panic("not supported") } + func (f *Functions) DeleteBuffer(v Buffer) { f._deleteBuffer.Invoke(js.Value(v)) } + func (f *Functions) DeleteFramebuffer(v Framebuffer) { f._deleteFramebuffer.Invoke(js.Value(v)) } + func (f *Functions) DeleteProgram(p Program) { f._deleteProgram.Invoke(js.Value(p)) } + func (f *Functions) DeleteQuery(query Query) { if !f.EXT_disjoint_timer_query_webgl2.IsNull() { f._deleteQuery.Invoke(js.Value(query)) @@ -363,45 +395,59 @@ func (f *Functions) DeleteQuery(query Query) { f.EXT_disjoint_timer_query.Call("deleteQueryEXT", js.Value(query)) } } + func (f *Functions) DeleteShader(s Shader) { f._deleteShader.Invoke(js.Value(s)) } + func (f *Functions) DeleteRenderbuffer(v Renderbuffer) { f._deleteRenderbuffer.Invoke(js.Value(v)) } + func (f *Functions) DeleteTexture(v Texture) { f._deleteTexture.Invoke(js.Value(v)) } + func (f *Functions) DeleteVertexArray(a VertexArray) { panic("not implemented") } + func (f *Functions) DepthFunc(fn Enum) { f._depthFunc.Invoke(int(fn)) } + func (f *Functions) DepthMask(mask bool) { f._depthMask.Invoke(mask) } + func (f *Functions) DisableVertexAttribArray(a Attrib) { f._disableVertexAttribArray.Invoke(int(a)) } + func (f *Functions) Disable(cap Enum) { f._disable.Invoke(int(cap)) } + func (f *Functions) DrawArrays(mode Enum, first, count int) { f._drawArrays.Invoke(int(mode), first, count) } + func (f *Functions) DrawElements(mode Enum, count int, ty Enum, offset int) { f._drawElements.Invoke(int(mode), count, int(ty), offset) } + func (f *Functions) DispatchCompute(x, y, z int) { panic("not implemented") } + func (f *Functions) Enable(cap Enum) { f._enable.Invoke(int(cap)) } + func (f *Functions) EnableVertexAttribArray(a Attrib) { f._enableVertexAttribArray.Invoke(int(a)) } + func (f *Functions) EndQuery(target Enum) { if !f.EXT_disjoint_timer_query_webgl2.IsNull() { f._endQuery.Invoke(int(target)) @@ -409,28 +455,36 @@ func (f *Functions) EndQuery(target Enum) { f.EXT_disjoint_timer_query.Call("endQueryEXT", int(target)) } } + func (f *Functions) Finish() { f._finish.Invoke() } + func (f *Functions) Flush() { f._flush.Invoke() } + func (f *Functions) FramebufferRenderbuffer(target, attachment, renderbuffertarget Enum, renderbuffer Renderbuffer) { f._framebufferRenderbuffer.Invoke(int(target), int(attachment), int(renderbuffertarget), js.Value(renderbuffer)) } + func (f *Functions) FramebufferTexture2D(target, attachment, texTarget Enum, t Texture, level int) { f._framebufferTexture2D.Invoke(int(target), int(attachment), int(texTarget), js.Value(t), level) } + func (f *Functions) GenerateMipmap(target Enum) { f._generateMipmap.Invoke(int(target)) } + func (f *Functions) GetError() Enum { // Avoid slow getError calls. See gio#179. return 0 } + func (f *Functions) GetRenderbufferParameteri(target, pname Enum) int { return paramVal(f._getRenderbufferParameteri.Invoke(int(pname))) } + func (f *Functions) GetFramebufferAttachmentParameteri(target, attachment, pname Enum) int { if !f.isWebGL2 && pname == FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING { // FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING is only available on WebGL 2 @@ -438,6 +492,7 @@ func (f *Functions) GetFramebufferAttachmentParameteri(target, attachment, pname } return paramVal(f._getFramebufferAttachmentParameter.Invoke(int(target), int(attachment), int(pname))) } + func (f *Functions) GetBinding(pname Enum) Object { obj := f._getParameter.Invoke(int(pname)) if !obj.Truthy() { @@ -445,6 +500,7 @@ func (f *Functions) GetBinding(pname Enum) Object { } return Object(obj) } + func (f *Functions) GetBindingi(pname Enum, idx int) Object { obj := f._getIndexedParameter.Invoke(int(pname), idx) if !obj.Truthy() { @@ -452,6 +508,7 @@ func (f *Functions) GetBindingi(pname Enum, idx int) Object { } return Object(obj) } + func (f *Functions) GetInteger(pname Enum) int { if !f.isWebGL2 { switch pname { @@ -461,9 +518,11 @@ func (f *Functions) GetInteger(pname Enum) int { } return paramVal(f._getParameter.Invoke(int(pname))) } + func (f *Functions) GetFloat(pname Enum) float32 { return float32(f._getParameter.Invoke(int(pname)).Float()) } + func (f *Functions) GetInteger4(pname Enum) [4]int { arr := f._getParameter.Invoke(int(pname)) var res [4]int @@ -472,6 +531,7 @@ func (f *Functions) GetInteger4(pname Enum) [4]int { } return res } + func (f *Functions) GetFloat4(pname Enum) [4]float32 { arr := f._getParameter.Invoke(int(pname)) var res [4]float32 @@ -480,12 +540,15 @@ func (f *Functions) GetFloat4(pname Enum) [4]float32 { } return res } + func (f *Functions) GetProgrami(p Program, pname Enum) int { return paramVal(f._getProgramParameter.Invoke(js.Value(p), int(pname))) } + func (f *Functions) GetProgramInfoLog(p Program) string { return f._getProgramInfoLog.Invoke(js.Value(p)).String() } + func (f *Functions) GetQueryObjectuiv(query Query, pname Enum) uint { if !f.EXT_disjoint_timer_query_webgl2.IsNull() { return uint(paramVal(f._getQueryParameter.Invoke(js.Value(query), int(pname)))) @@ -493,12 +556,15 @@ func (f *Functions) GetQueryObjectuiv(query Query, pname Enum) uint { return uint(paramVal(f.EXT_disjoint_timer_query.Call("getQueryObjectEXT", js.Value(query), int(pname)))) } } + func (f *Functions) GetShaderi(s Shader, pname Enum) int { return paramVal(f._getShaderParameter.Invoke(js.Value(s), int(pname))) } + func (f *Functions) GetShaderInfoLog(s Shader) string { return f._getShaderInfoLog.Invoke(js.Value(s)).String() } + func (f *Functions) GetString(pname Enum) string { switch pname { case EXTENSIONS: @@ -512,15 +578,19 @@ func (f *Functions) GetString(pname Enum) string { return f._getParameter.Invoke(int(pname)).String() } } + func (f *Functions) GetUniformBlockIndex(p Program, name string) uint { return uint(paramVal(f._getUniformBlockIndex.Invoke(js.Value(p), name))) } + func (f *Functions) GetUniformLocation(p Program, name string) Uniform { return Uniform(f._getUniformLocation.Invoke(js.Value(p), name)) } + func (f *Functions) GetVertexAttrib(index int, pname Enum) int { return paramVal(f._getVertexAttrib.Invoke(index, int(pname))) } + func (f *Functions) GetVertexAttribBinding(index int, pname Enum) Object { obj := f._getVertexAttrib.Invoke(index, int(pname)) if !obj.Truthy() { @@ -528,9 +598,11 @@ func (f *Functions) GetVertexAttribBinding(index int, pname Enum) Object { } return Object(obj) } + func (f *Functions) GetVertexAttribPointer(index int, pname Enum) uintptr { return uintptr(f._getVertexAttribOffset.Invoke(index, int(pname)).Int()) } + func (f *Functions) InvalidateFramebuffer(target, attachment Enum) { fn := f.Ctx.Get("invalidateFramebuffer") if !fn.IsUndefined() { @@ -541,74 +613,97 @@ func (f *Functions) InvalidateFramebuffer(target, attachment Enum) { f._invalidateFramebuffer.Invoke(int(target), f.int32Buf) } } + func (f *Functions) IsEnabled(cap Enum) bool { return f._isEnabled.Invoke(int(cap)).Truthy() } + func (f *Functions) LinkProgram(p Program) { f._linkProgram.Invoke(js.Value(p)) } + func (f *Functions) PixelStorei(pname Enum, param int) { f._pixelStorei.Invoke(int(pname), param) } + func (f *Functions) MemoryBarrier(barriers Enum) { panic("not implemented") } + func (f *Functions) MapBufferRange(target Enum, offset, length int, access Enum) []byte { panic("not implemented") } + func (f *Functions) RenderbufferStorage(target, internalformat Enum, width, height int) { f._renderbufferStorage.Invoke(int(target), int(internalformat), width, height) } + func (f *Functions) ReadPixels(x, y, width, height int, format, ty Enum, data []byte) { ba := f.byteArrayOf(data) f._readPixels.Invoke(x, y, width, height, int(format), int(ty), ba) js.CopyBytesToGo(data, ba) } + func (f *Functions) Scissor(x, y, width, height int32) { f._scissor.Invoke(x, y, width, height) } + func (f *Functions) ShaderSource(s Shader, src string) { f._shaderSource.Invoke(js.Value(s), src) } + func (f *Functions) TexImage2D(target Enum, level int, internalFormat Enum, width, height int, format, ty Enum) { f._texImage2D.Invoke(int(target), int(level), int(internalFormat), int(width), int(height), 0, int(format), int(ty), nil) } + func (f *Functions) TexStorage2D(target Enum, levels int, internalFormat Enum, width, height int) { f._texStorage2D.Invoke(int(target), levels, int(internalFormat), width, height) } + func (f *Functions) TexSubImage2D(target Enum, level int, x, y, width, height int, format, ty Enum, data []byte) { f._texSubImage2D.Invoke(int(target), level, x, y, width, height, int(format), int(ty), f.byteArrayOf(data)) } + func (f *Functions) TexParameteri(target, pname Enum, param int) { f._texParameteri.Invoke(int(target), int(pname), int(param)) } + func (f *Functions) UniformBlockBinding(p Program, uniformBlockIndex uint, uniformBlockBinding uint) { f._uniformBlockBinding.Invoke(js.Value(p), int(uniformBlockIndex), int(uniformBlockBinding)) } + func (f *Functions) Uniform1f(dst Uniform, v float32) { f._uniform1f.Invoke(js.Value(dst), v) } + func (f *Functions) Uniform1i(dst Uniform, v int) { f._uniform1i.Invoke(js.Value(dst), v) } + func (f *Functions) Uniform2f(dst Uniform, v0, v1 float32) { f._uniform2f.Invoke(js.Value(dst), v0, v1) } + func (f *Functions) Uniform3f(dst Uniform, v0, v1, v2 float32) { f._uniform3f.Invoke(js.Value(dst), v0, v1, v2) } + func (f *Functions) Uniform4f(dst Uniform, v0, v1, v2, v3 float32) { f._uniform4f.Invoke(js.Value(dst), v0, v1, v2, v3) } + func (f *Functions) UseProgram(p Program) { f._useProgram.Invoke(js.Value(p)) } + func (f *Functions) UnmapBuffer(target Enum) bool { panic("not implemented") } + func (f *Functions) VertexAttribPointer(dst Attrib, size int, ty Enum, normalized bool, stride, offset int) { f._vertexAttribPointer.Invoke(int(dst), size, int(ty), normalized, stride, offset) } + func (f *Functions) Viewport(x, y, width, height int) { f._viewport.Invoke(x, y, width, height) } diff --git a/internal/gl/gl_windows.go b/internal/gl/gl_windows.go index b4422e7e..5d6100d6 100644 --- a/internal/gl/gl_windows.go +++ b/internal/gl/gl_windows.go @@ -223,7 +223,7 @@ type Functions struct { uintptrs [100]uintptr } -type Context interface{} +type Context any func NewFunctions(ctx Context, forceES bool) (*Functions, error) { if ctx != nil { @@ -239,45 +239,58 @@ func NewFunctions(ctx Context, forceES bool) (*Functions, error) { func (c *Functions) ActiveTexture(t Enum) { syscall.Syscall(_glActiveTexture.Addr(), 1, uintptr(t), 0, 0) } + func (c *Functions) AttachShader(p Program, s Shader) { syscall.Syscall(_glAttachShader.Addr(), 2, uintptr(p.V), uintptr(s.V), 0) } + func (f *Functions) BeginQuery(target Enum, query Query) { syscall.Syscall(_glBeginQuery.Addr(), 2, uintptr(target), uintptr(query.V), 0) } + func (c *Functions) BindAttribLocation(p Program, a Attrib, name string) { cname := cString(name) c0 := &cname[0] syscall.Syscall(_glBindAttribLocation.Addr(), 3, uintptr(p.V), uintptr(a), uintptr(unsafe.Pointer(c0))) issue34474KeepAlive(c) } + func (c *Functions) BindBuffer(target Enum, b Buffer) { syscall.Syscall(_glBindBuffer.Addr(), 2, uintptr(target), uintptr(b.V), 0) } + func (c *Functions) BindBufferBase(target Enum, index int, b Buffer) { syscall.Syscall(_glBindBufferBase.Addr(), 3, uintptr(target), uintptr(index), uintptr(b.V)) } + func (c *Functions) BindFramebuffer(target Enum, fb Framebuffer) { syscall.Syscall(_glBindFramebuffer.Addr(), 2, uintptr(target), uintptr(fb.V), 0) } + func (c *Functions) BindRenderbuffer(target Enum, rb Renderbuffer) { syscall.Syscall(_glBindRenderbuffer.Addr(), 2, uintptr(target), uintptr(rb.V), 0) } + func (f *Functions) BindImageTexture(unit int, t Texture, level int, layered bool, layer int, access, format Enum) { panic("not implemented") } + func (c *Functions) BindTexture(target Enum, t Texture) { syscall.Syscall(_glBindTexture.Addr(), 2, uintptr(target), uintptr(t.V), 0) } + func (c *Functions) BindVertexArray(a VertexArray) { syscall.Syscall(_glBindVertexArray.Addr(), 1, uintptr(a.V), 0, 0) } + func (c *Functions) BlendEquation(mode Enum) { syscall.Syscall(_glBlendEquation.Addr(), 1, uintptr(mode), 0, 0) } + func (c *Functions) BlendFuncSeparate(srcRGB, dstRGB, srcA, dstA Enum) { syscall.Syscall6(_glBlendFuncSeparate.Addr(), 4, uintptr(srcRGB), uintptr(dstRGB), uintptr(srcA), uintptr(dstA), 0, 0) } + func (c *Functions) BufferData(target Enum, size int, usage Enum, data []byte) { var p unsafe.Pointer if len(data) > 0 { @@ -285,6 +298,7 @@ func (c *Functions) BufferData(target Enum, size int, usage Enum, data []byte) { } syscall.Syscall6(_glBufferData.Addr(), 4, uintptr(target), uintptr(size), uintptr(p), uintptr(usage), 0, 0) } + func (f *Functions) BufferSubData(target Enum, offset int, src []byte) { if n := len(src); n > 0 { s0 := &src[0] @@ -292,93 +306,118 @@ func (f *Functions) BufferSubData(target Enum, offset int, src []byte) { issue34474KeepAlive(s0) } } + func (c *Functions) CheckFramebufferStatus(target Enum) Enum { s, _, _ := syscall.Syscall(_glCheckFramebufferStatus.Addr(), 1, uintptr(target), 0, 0) return Enum(s) } + func (c *Functions) Clear(mask Enum) { syscall.Syscall(_glClear.Addr(), 1, uintptr(mask), 0, 0) } + func (c *Functions) ClearColor(red, green, blue, alpha float32) { syscall.Syscall6(_glClearColor.Addr(), 4, uintptr(math.Float32bits(red)), uintptr(math.Float32bits(green)), uintptr(math.Float32bits(blue)), uintptr(math.Float32bits(alpha)), 0, 0) } + func (c *Functions) ClearDepthf(d float32) { syscall.Syscall(_glClearDepthf.Addr(), 1, uintptr(math.Float32bits(d)), 0, 0) } + func (c *Functions) CompileShader(s Shader) { syscall.Syscall(_glCompileShader.Addr(), 1, uintptr(s.V), 0, 0) } + func (f *Functions) CopyTexSubImage2D(target Enum, level, xoffset, yoffset, x, y, width, height int) { syscall.Syscall9(_glCopyTexSubImage2D.Addr(), 8, uintptr(target), uintptr(level), uintptr(xoffset), uintptr(yoffset), uintptr(x), uintptr(y), uintptr(width), uintptr(height), 0) } + func (f *Functions) GenerateMipmap(target Enum) { syscall.Syscall(_glGenerateMipmap.Addr(), 1, uintptr(target), 0, 0) } + func (c *Functions) CreateBuffer() Buffer { var buf uintptr syscall.Syscall(_glGenBuffers.Addr(), 2, 1, uintptr(unsafe.Pointer(&buf)), 0) return Buffer{uint(buf)} } + func (c *Functions) CreateFramebuffer() Framebuffer { var fb uintptr syscall.Syscall(_glGenFramebuffers.Addr(), 2, 1, uintptr(unsafe.Pointer(&fb)), 0) return Framebuffer{uint(fb)} } + func (c *Functions) CreateProgram() Program { p, _, _ := syscall.Syscall(_glCreateProgram.Addr(), 0, 0, 0, 0) return Program{uint(p)} } + func (f *Functions) CreateQuery() Query { var q uintptr syscall.Syscall(_glGenQueries.Addr(), 2, 1, uintptr(unsafe.Pointer(&q)), 0) return Query{uint(q)} } + func (c *Functions) CreateRenderbuffer() Renderbuffer { var rb uintptr syscall.Syscall(_glGenRenderbuffers.Addr(), 2, 1, uintptr(unsafe.Pointer(&rb)), 0) return Renderbuffer{uint(rb)} } + func (c *Functions) CreateShader(ty Enum) Shader { s, _, _ := syscall.Syscall(_glCreateShader.Addr(), 1, uintptr(ty), 0, 0) return Shader{uint(s)} } + func (c *Functions) CreateTexture() Texture { var t uintptr syscall.Syscall(_glGenTextures.Addr(), 2, 1, uintptr(unsafe.Pointer(&t)), 0) return Texture{uint(t)} } + func (c *Functions) CreateVertexArray() VertexArray { var t uintptr syscall.Syscall(_glGenVertexArrays.Addr(), 2, 1, uintptr(unsafe.Pointer(&t)), 0) return VertexArray{uint(t)} } + func (c *Functions) DeleteBuffer(v Buffer) { syscall.Syscall(_glDeleteBuffers.Addr(), 2, 1, uintptr(unsafe.Pointer(&v)), 0) } + func (c *Functions) DeleteFramebuffer(v Framebuffer) { syscall.Syscall(_glDeleteFramebuffers.Addr(), 2, 1, uintptr(unsafe.Pointer(&v.V)), 0) } + func (c *Functions) DeleteProgram(p Program) { syscall.Syscall(_glDeleteProgram.Addr(), 1, uintptr(p.V), 0, 0) } + func (f *Functions) DeleteQuery(query Query) { syscall.Syscall(_glDeleteQueries.Addr(), 2, 1, uintptr(unsafe.Pointer(&query.V)), 0) } + func (c *Functions) DeleteShader(s Shader) { syscall.Syscall(_glDeleteShader.Addr(), 1, uintptr(s.V), 0, 0) } + func (c *Functions) DeleteRenderbuffer(v Renderbuffer) { syscall.Syscall(_glDeleteRenderbuffers.Addr(), 2, 1, uintptr(unsafe.Pointer(&v.V)), 0) } + func (c *Functions) DeleteTexture(v Texture) { syscall.Syscall(_glDeleteTextures.Addr(), 2, 1, uintptr(unsafe.Pointer(&v.V)), 0) } + func (f *Functions) DeleteVertexArray(array VertexArray) { syscall.Syscall(_glDeleteVertexArrays.Addr(), 2, 1, uintptr(unsafe.Pointer(&array.V)), 0) } + func (c *Functions) DepthFunc(f Enum) { syscall.Syscall(_glDepthFunc.Addr(), 1, uintptr(f), 0, 0) } + func (c *Functions) DepthMask(mask bool) { var m uintptr if mask { @@ -386,42 +425,55 @@ func (c *Functions) DepthMask(mask bool) { } syscall.Syscall(_glDepthMask.Addr(), 1, m, 0, 0) } + func (c *Functions) DisableVertexAttribArray(a Attrib) { syscall.Syscall(_glDisableVertexAttribArray.Addr(), 1, uintptr(a), 0, 0) } + func (c *Functions) Disable(cap Enum) { syscall.Syscall(_glDisable.Addr(), 1, uintptr(cap), 0, 0) } + func (c *Functions) DrawArrays(mode Enum, first, count int) { syscall.Syscall(_glDrawArrays.Addr(), 3, uintptr(mode), uintptr(first), uintptr(count)) } + func (c *Functions) DrawElements(mode Enum, count int, ty Enum, offset int) { syscall.Syscall6(_glDrawElements.Addr(), 4, uintptr(mode), uintptr(count), uintptr(ty), uintptr(offset), 0, 0) } + func (f *Functions) DispatchCompute(x, y, z int) { panic("not implemented") } + func (c *Functions) Enable(cap Enum) { syscall.Syscall(_glEnable.Addr(), 1, uintptr(cap), 0, 0) } + func (c *Functions) EnableVertexAttribArray(a Attrib) { syscall.Syscall(_glEnableVertexAttribArray.Addr(), 1, uintptr(a), 0, 0) } + func (f *Functions) EndQuery(target Enum) { syscall.Syscall(_glEndQuery.Addr(), 1, uintptr(target), 0, 0) } + func (c *Functions) Finish() { syscall.Syscall(_glFinish.Addr(), 0, 0, 0, 0) } + func (c *Functions) Flush() { syscall.Syscall(_glFlush.Addr(), 0, 0, 0, 0) } + func (c *Functions) FramebufferRenderbuffer(target, attachment, renderbuffertarget Enum, renderbuffer Renderbuffer) { syscall.Syscall6(_glFramebufferRenderbuffer.Addr(), 4, uintptr(target), uintptr(attachment), uintptr(renderbuffertarget), uintptr(renderbuffer.V), 0, 0) } + func (c *Functions) FramebufferTexture2D(target, attachment, texTarget Enum, t Texture, level int) { syscall.Syscall6(_glFramebufferTexture2D.Addr(), 5, uintptr(target), uintptr(attachment), uintptr(texTarget), uintptr(t.V), uintptr(level), 0) } + func (f *Functions) GetUniformBlockIndex(p Program, name string) uint { cname := cString(name) c0 := &cname[0] @@ -429,24 +481,30 @@ func (f *Functions) GetUniformBlockIndex(p Program, name string) uint { issue34474KeepAlive(c0) return uint(u) } + func (c *Functions) GetBinding(pname Enum) Object { return Object{uint(c.GetInteger(pname))} } + func (c *Functions) GetBindingi(pname Enum, idx int) Object { return Object{uint(c.GetIntegeri(pname, idx))} } + func (c *Functions) GetError() Enum { e, _, _ := syscall.Syscall(_glGetError.Addr(), 0, 0, 0, 0) return Enum(e) } + func (c *Functions) GetRenderbufferParameteri(target, pname Enum) int { syscall.Syscall(_glGetRenderbufferParameteriv.Addr(), 3, uintptr(target), uintptr(pname), uintptr(unsafe.Pointer(&c.int32s[0]))) return int(c.int32s[0]) } + func (c *Functions) GetFramebufferAttachmentParameteri(target, attachment, pname Enum) int { syscall.Syscall6(_glGetFramebufferAttachmentParameteriv.Addr(), 4, uintptr(target), uintptr(attachment), uintptr(pname), uintptr(unsafe.Pointer(&c.int32s[0])), 0, 0) return int(c.int32s[0]) } + func (c *Functions) GetInteger4(pname Enum) [4]int { syscall.Syscall(_glGetIntegerv.Addr(), 2, uintptr(pname), uintptr(unsafe.Pointer(&c.int32s[0])), 0) var r [4]int @@ -455,28 +513,34 @@ func (c *Functions) GetInteger4(pname Enum) [4]int { } return r } + func (c *Functions) GetInteger(pname Enum) int { syscall.Syscall(_glGetIntegerv.Addr(), 2, uintptr(pname), uintptr(unsafe.Pointer(&c.int32s[0])), 0) return int(c.int32s[0]) } + func (c *Functions) GetIntegeri(pname Enum, idx int) int { syscall.Syscall(_glGetIntegeri_v.Addr(), 3, uintptr(pname), uintptr(idx), uintptr(unsafe.Pointer(&c.int32s[0]))) return int(c.int32s[0]) } + func (c *Functions) GetFloat(pname Enum) float32 { syscall.Syscall(_glGetFloatv.Addr(), 2, uintptr(pname), uintptr(unsafe.Pointer(&c.float32s[0])), 0) return c.float32s[0] } + func (c *Functions) GetFloat4(pname Enum) [4]float32 { syscall.Syscall(_glGetFloatv.Addr(), 2, uintptr(pname), uintptr(unsafe.Pointer(&c.float32s[0])), 0) var r [4]float32 copy(r[:], c.float32s[:]) return r } + func (c *Functions) GetProgrami(p Program, pname Enum) int { syscall.Syscall(_glGetProgramiv.Addr(), 3, uintptr(p.V), uintptr(pname), uintptr(unsafe.Pointer(&c.int32s[0]))) return int(c.int32s[0]) } + func (c *Functions) GetProgramInfoLog(p Program) string { n := c.GetProgrami(p, INFO_LOG_LENGTH) if n == 0 { @@ -486,24 +550,29 @@ func (c *Functions) GetProgramInfoLog(p Program) string { syscall.Syscall6(_glGetProgramInfoLog.Addr(), 4, uintptr(p.V), uintptr(len(buf)), 0, uintptr(unsafe.Pointer(&buf[0])), 0, 0) return string(buf) } + func (c *Functions) GetQueryObjectuiv(query Query, pname Enum) uint { syscall.Syscall(_glGetQueryObjectuiv.Addr(), 3, uintptr(query.V), uintptr(pname), uintptr(unsafe.Pointer(&c.int32s[0]))) return uint(c.int32s[0]) } + func (c *Functions) GetShaderi(s Shader, pname Enum) int { syscall.Syscall(_glGetShaderiv.Addr(), 3, uintptr(s.V), uintptr(pname), uintptr(unsafe.Pointer(&c.int32s[0]))) return int(c.int32s[0]) } + func (c *Functions) GetShaderInfoLog(s Shader) string { n := c.GetShaderi(s, INFO_LOG_LENGTH) buf := make([]byte, n) syscall.Syscall6(_glGetShaderInfoLog.Addr(), 4, uintptr(s.V), uintptr(len(buf)), 0, uintptr(unsafe.Pointer(&buf[0])), 0, 0) return string(buf) } + func (c *Functions) GetString(pname Enum) string { s, _, _ := syscall.Syscall(_glGetString.Addr(), 1, uintptr(pname), 0, 0) return windows.BytePtrToString((*byte)(unsafe.Pointer(s))) } + func (c *Functions) GetUniformLocation(p Program, name string) Uniform { cname := cString(name) c0 := &cname[0] @@ -511,6 +580,7 @@ func (c *Functions) GetUniformLocation(p Program, name string) Uniform { issue34474KeepAlive(c0) return Uniform{int(u)} } + func (c *Functions) GetVertexAttrib(index int, pname Enum) int { syscall.Syscall(_glGetVertexAttribiv.Addr(), 3, uintptr(index), uintptr(pname), uintptr(unsafe.Pointer(&c.int32s[0]))) return int(c.int32s[0]) @@ -524,6 +594,7 @@ func (c *Functions) GetVertexAttribPointer(index int, pname Enum) uintptr { syscall.Syscall(_glGetVertexAttribPointerv.Addr(), 3, uintptr(index), uintptr(pname), uintptr(unsafe.Pointer(&c.uintptrs[0]))) return c.uintptrs[0] } + func (c *Functions) InvalidateFramebuffer(target, attachment Enum) { addr := _glInvalidateFramebuffer.Addr() if addr == 0 { @@ -532,77 +603,99 @@ func (c *Functions) InvalidateFramebuffer(target, attachment Enum) { } syscall.Syscall(addr, 3, uintptr(target), 1, uintptr(unsafe.Pointer(&attachment))) } + func (f *Functions) IsEnabled(cap Enum) bool { u, _, _ := syscall.Syscall(_glIsEnabled.Addr(), 1, uintptr(cap), 0, 0) return u == TRUE } + func (c *Functions) LinkProgram(p Program) { syscall.Syscall(_glLinkProgram.Addr(), 1, uintptr(p.V), 0, 0) } + func (c *Functions) PixelStorei(pname Enum, param int) { syscall.Syscall(_glPixelStorei.Addr(), 2, uintptr(pname), uintptr(param), 0) } + func (f *Functions) MemoryBarrier(barriers Enum) { panic("not implemented") } + func (f *Functions) MapBufferRange(target Enum, offset, length int, access Enum) []byte { panic("not implemented") } + func (f *Functions) ReadPixels(x, y, width, height int, format, ty Enum, data []byte) { d0 := &data[0] syscall.Syscall9(_glReadPixels.Addr(), 7, uintptr(x), uintptr(y), uintptr(width), uintptr(height), uintptr(format), uintptr(ty), uintptr(unsafe.Pointer(d0)), 0, 0) issue34474KeepAlive(d0) } + func (c *Functions) RenderbufferStorage(target, internalformat Enum, width, height int) { syscall.Syscall6(_glRenderbufferStorage.Addr(), 4, uintptr(target), uintptr(internalformat), uintptr(width), uintptr(height), 0, 0) } + func (c *Functions) Scissor(x, y, width, height int32) { syscall.Syscall6(_glScissor.Addr(), 4, uintptr(x), uintptr(y), uintptr(width), uintptr(height), 0, 0) } + func (c *Functions) ShaderSource(s Shader, src string) { var n uintptr = uintptr(len(src)) psrc := &src syscall.Syscall6(_glShaderSource.Addr(), 4, uintptr(s.V), 1, uintptr(unsafe.Pointer(psrc)), uintptr(unsafe.Pointer(&n)), 0, 0) issue34474KeepAlive(psrc) } + func (f *Functions) TexImage2D(target Enum, level int, internalFormat Enum, width int, height int, format Enum, ty Enum) { syscall.Syscall9(_glTexImage2D.Addr(), 9, uintptr(target), uintptr(level), uintptr(internalFormat), uintptr(width), uintptr(height), 0, uintptr(format), uintptr(ty), 0) } + func (f *Functions) TexStorage2D(target Enum, levels int, internalFormat Enum, width, height int) { syscall.Syscall6(_glTexStorage2D.Addr(), 5, uintptr(target), uintptr(levels), uintptr(internalFormat), uintptr(width), uintptr(height), 0) } + func (c *Functions) TexSubImage2D(target Enum, level int, x, y, width, height int, format, ty Enum, data []byte) { d0 := &data[0] syscall.Syscall9(_glTexSubImage2D.Addr(), 9, uintptr(target), uintptr(level), uintptr(x), uintptr(y), uintptr(width), uintptr(height), uintptr(format), uintptr(ty), uintptr(unsafe.Pointer(d0))) issue34474KeepAlive(d0) } + func (c *Functions) TexParameteri(target, pname Enum, param int) { syscall.Syscall(_glTexParameteri.Addr(), 3, uintptr(target), uintptr(pname), uintptr(param)) } + func (f *Functions) UniformBlockBinding(p Program, uniformBlockIndex uint, uniformBlockBinding uint) { syscall.Syscall(_glUniformBlockBinding.Addr(), 3, uintptr(p.V), uintptr(uniformBlockIndex), uintptr(uniformBlockBinding)) } + func (c *Functions) Uniform1f(dst Uniform, v float32) { syscall.Syscall(_glUniform1f.Addr(), 2, uintptr(dst.V), uintptr(math.Float32bits(v)), 0) } + func (c *Functions) Uniform1i(dst Uniform, v int) { syscall.Syscall(_glUniform1i.Addr(), 2, uintptr(dst.V), uintptr(v), 0) } + func (c *Functions) Uniform2f(dst Uniform, v0, v1 float32) { syscall.Syscall(_glUniform2f.Addr(), 3, uintptr(dst.V), uintptr(math.Float32bits(v0)), uintptr(math.Float32bits(v1))) } + func (c *Functions) Uniform3f(dst Uniform, v0, v1, v2 float32) { syscall.Syscall6(_glUniform3f.Addr(), 4, uintptr(dst.V), uintptr(math.Float32bits(v0)), uintptr(math.Float32bits(v1)), uintptr(math.Float32bits(v2)), 0, 0) } + func (c *Functions) Uniform4f(dst Uniform, v0, v1, v2, v3 float32) { syscall.Syscall6(_glUniform4f.Addr(), 5, uintptr(dst.V), uintptr(math.Float32bits(v0)), uintptr(math.Float32bits(v1)), uintptr(math.Float32bits(v2)), uintptr(math.Float32bits(v3)), 0) } + func (c *Functions) UseProgram(p Program) { syscall.Syscall(_glUseProgram.Addr(), 1, uintptr(p.V), 0, 0) } + func (f *Functions) UnmapBuffer(target Enum) bool { panic("not implemented") } + func (c *Functions) VertexAttribPointer(dst Attrib, size int, ty Enum, normalized bool, stride, offset int) { var norm uintptr if normalized { @@ -610,6 +703,7 @@ func (c *Functions) VertexAttribPointer(dst Attrib, size int, ty Enum, normalize } syscall.Syscall6(_glVertexAttribPointer.Addr(), 6, uintptr(dst), uintptr(size), uintptr(ty), norm, uintptr(stride), uintptr(offset)) } + func (c *Functions) Viewport(x, y, width, height int) { syscall.Syscall6(_glViewport.Addr(), 4, uintptr(x), uintptr(y), uintptr(width), uintptr(height), 0, 0) } @@ -622,6 +716,6 @@ func cString(s string) []byte { // issue34474KeepAlive calls runtime.KeepAlive as a // workaround for golang.org/issue/34474. -func issue34474KeepAlive(v interface{}) { +func issue34474KeepAlive(v any) { runtime.KeepAlive(v) } diff --git a/internal/ops/ops.go b/internal/ops/ops.go index e0cae3a7..591f87d2 100644 --- a/internal/ops/ops.go +++ b/internal/ops/ops.go @@ -18,7 +18,7 @@ type Ops struct { // data contains the serialized operations. data []byte // refs hold external references for operations. - refs []interface{} + refs []any // stringRefs provides space for string references, pointers to which will // be stored in refs. Storing a string directly in refs would cause a heap // allocation, to store the string header in an interface value. The backing @@ -256,7 +256,7 @@ func PopOp(o *Ops, kind StackKind, sid StackID, macroID uint32) { o.stacks[kind].pop(sid) } -func Write1(o *Ops, n int, ref1 interface{}) []byte { +func Write1(o *Ops, n int, ref1 any) []byte { o.data = append(o.data, make([]byte, n)...) o.refs = append(o.refs, ref1) return o.data[len(o.data)-n:] @@ -269,20 +269,20 @@ func Write1String(o *Ops, n int, ref1 string) []byte { return o.data[len(o.data)-n:] } -func Write2(o *Ops, n int, ref1, ref2 interface{}) []byte { +func Write2(o *Ops, n int, ref1, ref2 any) []byte { o.data = append(o.data, make([]byte, n)...) o.refs = append(o.refs, ref1, ref2) return o.data[len(o.data)-n:] } -func Write2String(o *Ops, n int, ref1 interface{}, ref2 string) []byte { +func Write2String(o *Ops, n int, ref1 any, ref2 string) []byte { o.data = append(o.data, make([]byte, n)...) o.stringRefs = append(o.stringRefs, ref2) o.refs = append(o.refs, ref1, &o.stringRefs[len(o.stringRefs)-1]) return o.data[len(o.data)-n:] } -func Write3(o *Ops, n int, ref1, ref2, ref3 interface{}) []byte { +func Write3(o *Ops, n int, ref1, ref2, ref3 any) []byte { o.data = append(o.data, make([]byte, n)...) o.refs = append(o.refs, ref1, ref2, ref3) return o.data[len(o.data)-n:] diff --git a/internal/ops/reader.go b/internal/ops/reader.go index 5ed78ff7..8964ec67 100644 --- a/internal/ops/reader.go +++ b/internal/ops/reader.go @@ -20,7 +20,7 @@ type Reader struct { type EncodedOp struct { Key Key Data []byte - Refs []interface{} + Refs []any } // Key is a unique key for a given op. @@ -175,7 +175,7 @@ func (op *opMacroDef) decode(data []byte) { op.endpc.refs = bo.Uint32(data[5:]) } -func (m *macroOp) decode(data []byte, refs []interface{}) { +func (m *macroOp) decode(data []byte, refs []any) { if len(data) < TypeCallLen || len(refs) < 1 || OpType(data[0]) != TypeCall { panic("invalid op") } diff --git a/internal/stroke/stroke.go b/internal/stroke/stroke.go index 1a647de5..7f1ec366 100644 --- a/internal/stroke/stroke.go +++ b/internal/stroke/stroke.go @@ -87,7 +87,7 @@ func (qs *StrokeQuads) lineTo(pt f32.Point) { func (qs *StrokeQuads) arc(f1, f2 f32.Point, angle float32) { pen := qs.pen() m, segments := ArcTransform(pen, f1.Add(pen), f2.Add(pen), angle) - for i := 0; i < segments; i++ { + for range segments { p0 := qs.pen() p1 := m.Transform(p0) p2 := m.Transform(p1) @@ -440,7 +440,6 @@ func flattenQuadBezier(qs StrokeQuads, p0, p1, p2 f32.Point, d, flatness float32 } func (qs *StrokeQuads) addLine(p0, ctrl, p1 f32.Point, t, d float32) { - switch i := len(*qs); i { case 0: p0 = p0.Add(strokePathNorm(p0, ctrl, p1, 0, d)) @@ -473,7 +472,6 @@ func quadInterp(p, q f32.Point, t float32) f32.Point { // quadBezierSplit returns the pair of triplets (from,ctrl,to) Bézier curve, // split before (resp. after) the provided parametric t value. func quadBezierSplit(p0, p1, p2 f32.Point, t float32) (f32.Point, f32.Point, f32.Point, f32.Point, f32.Point, f32.Point) { - var ( b0 = p0 b1 = quadInterp(p0, p1, t) diff --git a/internal/stroke/stroke_test.go b/internal/stroke/stroke_test.go index b6ffc547..30814138 100644 --- a/internal/stroke/stroke_test.go +++ b/internal/stroke/stroke_test.go @@ -52,7 +52,7 @@ func BenchmarkSplitCubic(b *testing.B) { from, ctrl0, ctrl1, to := s.from, s.ctrl0, s.ctrl1, s.to quads := make([]QuadSegment, s.segments) b.ResetTimer() - for i := 0; i < b.N; i++ { + for b.Loop() { quads = SplitCubic(from, ctrl0, ctrl1, to, quads[:0]) } if len(quads) != s.segments { diff --git a/internal/vk/vulkan.go b/internal/vk/vulkan.go index 63e5e3aa..343516d1 100644 --- a/internal/vk/vulkan.go +++ b/internal/vk/vulkan.go @@ -385,6 +385,7 @@ static VkResult vkQueuePresentKHR(PFN_vkQueuePresentKHR f, VkQueue queue, const } */ import "C" + import ( "errors" "fmt" @@ -1167,7 +1168,6 @@ func CreateFramebuffer(d Device, rp RenderPass, view ImageView, width, height in return nilFramebuffer, fmt.Errorf("vulkan: vkCreateFramebuffer: %w", err) } return fbo, nil - } func DestroyFramebuffer(d Device, f Framebuffer) { diff --git a/internal/vk/vulkan_android.go b/internal/vk/vulkan_android.go index 143146ef..cc9d8d22 100644 --- a/internal/vk/vulkan_android.go +++ b/internal/vk/vulkan_android.go @@ -17,6 +17,7 @@ static VkResult vkCreateAndroidSurfaceKHR(PFN_vkCreateAndroidSurfaceKHR f, VkIns } */ import "C" + import ( "fmt" "unsafe" diff --git a/internal/vk/vulkan_wayland.go b/internal/vk/vulkan_wayland.go index f503df44..798878ed 100644 --- a/internal/vk/vulkan_wayland.go +++ b/internal/vk/vulkan_wayland.go @@ -19,6 +19,7 @@ static VkResult vkCreateWaylandSurfaceKHR(PFN_vkCreateWaylandSurfaceKHR f, VkIns } */ import "C" + import ( "fmt" "unsafe" diff --git a/internal/vk/vulkan_x11.go b/internal/vk/vulkan_x11.go index 780a5d52..fe6bcfcb 100644 --- a/internal/vk/vulkan_x11.go +++ b/internal/vk/vulkan_x11.go @@ -17,6 +17,7 @@ static VkResult vkCreateXlibSurfaceKHR(PFN_vkCreateXlibSurfaceKHR f, VkInstance } */ import "C" + import ( "fmt" "unsafe" diff --git a/io/event/event.go b/io/event/event.go index a92342f7..2354d455 100644 --- a/io/event/event.go +++ b/io/event/event.go @@ -10,7 +10,7 @@ import ( // Tag is the stable identifier for an event handler. // For a handler h, the tag is typically &h. -type Tag interface{} +type Tag any // Event is the marker interface for events. type Event interface { diff --git a/io/input/clipboard.go b/io/input/clipboard.go index 3f40f6d9..7741c8a1 100644 --- a/io/input/clipboard.go +++ b/io/input/clipboard.go @@ -4,6 +4,7 @@ package input import ( "io" + "slices" "gioui.org/io/clipboard" "gioui.org/io/event" @@ -60,10 +61,8 @@ func (q *clipboardQueue) ProcessWriteClipboard(req clipboard.WriteCmd) { } func (q *clipboardQueue) ProcessReadClipboard(state clipboardState, tag event.Tag) clipboardState { - for _, k := range state.receivers { - if k == tag { - return state - } + if slices.Contains(state.receivers, tag) { + return state } n := len(state.receivers) state.receivers = append(state.receivers[:n:n], tag) diff --git a/io/input/clipboard_test.go b/io/input/clipboard_test.go index 9dc8ab52..64e183e6 100644 --- a/io/input/clipboard_test.go +++ b/io/input/clipboard_test.go @@ -52,7 +52,7 @@ func TestQueueProcessReadClipboard(t *testing.T) { assertClipboardReadCmd(t, r, 1) ops.Reset() - for i := 0; i < 3; i++ { + for range 3 { // No ReadCmd // One receiver must still wait for response diff --git a/io/input/key.go b/io/input/key.go index b5006f31..c9c6216c 100644 --- a/io/input/key.go +++ b/io/input/key.go @@ -4,6 +4,7 @@ package input import ( "image" + "slices" "sort" "gioui.org/f32" @@ -304,10 +305,8 @@ func (s keyState) softKeyboard(show bool) keyState { } func (k *keyFilter) Add(f key.Filter) { - for _, f2 := range *k { - if f == f2 { - return - } + if slices.Contains(*k, f) { + return } *k = append(*k, f) } diff --git a/io/input/pointer.go b/io/input/pointer.go index 329e7bc3..5cef405a 100644 --- a/io/input/pointer.go +++ b/io/input/pointer.go @@ -5,6 +5,7 @@ package input import ( "image" "io" + "slices" "gioui.org/f32" f32internal "gioui.org/internal/f32" @@ -258,13 +259,7 @@ func (q *pointerQueue) grab(state pointerState, req pointer.GrabCmd) (pointerSta continue } // Verify that the grabber is among the handlers. - found := false - for _, tag := range p.handlers { - if tag == req.Tag { - found = true - break - } - } + found := slices.Contains(p.handlers, req.Tag) if !found { continue } @@ -293,17 +288,13 @@ func (c *pointerCollector) inputOp(tag event.Tag, state *pointerHandler) { func (p *pointerFilter) Add(f event.Filter) { switch f := f.(type) { case transfer.SourceFilter: - for _, m := range p.sourceMimes { - if m == f.Type { - return - } + if slices.Contains(p.sourceMimes, f.Type) { + return } p.sourceMimes = append(p.sourceMimes, f.Type) case transfer.TargetFilter: - for _, m := range p.targetMimes { - if m == f.Type { - return - } + if slices.Contains(p.targetMimes, f.Type) { + return } p.targetMimes = append(p.targetMimes, f.Type) case pointer.Filter: @@ -320,16 +311,12 @@ func (p *pointerFilter) Matches(e event.Event) bool { case transfer.CancelEvent, transfer.InitiateEvent: return len(p.sourceMimes) > 0 || len(p.targetMimes) > 0 case transfer.RequestEvent: - for _, t := range p.sourceMimes { - if t == e.Type { - return true - } + if slices.Contains(p.sourceMimes, e.Type) { + return true } case transfer.DataEvent: - for _, t := range p.targetMimes { - if t == e.Type { - return true - } + if slices.Contains(p.targetMimes, e.Type) { + return true } } return false @@ -424,7 +411,7 @@ func (q *pointerQueue) offerData(handlers map[event.Tag]*handler, state pointerS }, }}) } - state.pointers = append([]pointerInfo{}, state.pointers...) + state.pointers = slices.Clone(state.pointers) state.pointers[i], evts = q.deliverTransferCancelEvent(handlers, p, evts) break } @@ -616,7 +603,7 @@ func (q *pointerQueue) reset() { for k, ids := range q.semantic.contentIDs { for i := len(ids) - 1; i >= 0; i-- { if !ids[i].used { - ids = append(ids[:i], ids[i+1:]...) + ids = slices.Delete(ids, i, i+1) } else { ids[i].used = false } @@ -647,7 +634,7 @@ func (q *pointerQueue) Frame(handlers map[event.Tag]*handler, state pointerState changed := false p, evts, state.cursor, changed = q.deliverEnterLeaveEvents(handlers, state.cursor, p, evts, p.last) if changed { - state.pointers = append([]pointerInfo{}, state.pointers...) + state.pointers = slices.Clone(state.pointers) state.pointers[i] = p } } @@ -783,9 +770,9 @@ func (q *pointerQueue) Push(handlers map[event.Tag]*handler, state pointerState, if !p.pressed && len(p.entered) == 0 { // No longer need to track pointer. - state.pointers = append(state.pointers[:pidx:pidx], state.pointers[pidx+1:]...) + state.pointers = slices.Concat(state.pointers[:pidx:pidx], state.pointers[pidx+1:]) } else { - state.pointers = append([]pointerInfo{}, state.pointers...) + state.pointers = slices.Clone(state.pointers) state.pointers[pidx] = p } return state, evts @@ -975,10 +962,8 @@ func searchTag(tags []event.Tag, tag event.Tag) (int, bool) { // addHandler adds tag to the slice if not present. func addHandler(tags []event.Tag, tag event.Tag) []event.Tag { - for _, t := range tags { - if t == tag { - return tags - } + if slices.Contains(tags, tag) { + return tags } return append(tags, tag) } @@ -986,10 +971,8 @@ func addHandler(tags []event.Tag, tag event.Tag) []event.Tag { // firstMimeMatch returns the first type match between src and tgt. func firstMimeMatch(src, tgt *pointerFilter) (first string, matched bool) { for _, m1 := range tgt.targetMimes { - for _, m2 := range src.sourceMimes { - if m1 == m2 { - return m1, true - } + if slices.Contains(src.sourceMimes, m1) { + return m1, true } } return "", false diff --git a/io/input/pointer_test.go b/io/input/pointer_test.go index 281623ca..fbe92a8a 100644 --- a/io/input/pointer_test.go +++ b/io/input/pointer_test.go @@ -711,26 +711,31 @@ func TestCursor(t *testing.T) { cursors []pointer.Cursor want pointer.Cursor }{ - {label: "no movement", + { + label: "no movement", cursors: []pointer.Cursor{pointer.CursorPointer}, want: pointer.CursorDefault, }, - {label: "move inside", + { + label: "move inside", cursors: []pointer.Cursor{pointer.CursorPointer}, events: _at(50, 50), want: pointer.CursorPointer, }, - {label: "move outside", + { + label: "move outside", cursors: []pointer.Cursor{pointer.CursorPointer}, events: _at(200, 200), want: pointer.CursorDefault, }, - {label: "move back inside", + { + label: "move back inside", cursors: []pointer.Cursor{pointer.CursorPointer}, events: _at(50, 50), want: pointer.CursorPointer, }, - {label: "send key events while inside", + { + label: "send key events while inside", cursors: []pointer.Cursor{pointer.CursorPointer}, events: []event.Event{ key.Event{Name: "A", State: key.Press}, @@ -738,7 +743,8 @@ func TestCursor(t *testing.T) { }, want: pointer.CursorPointer, }, - {label: "send key events while outside", + { + label: "send key events while outside", cursors: []pointer.Cursor{pointer.CursorPointer}, events: append( _at(200, 200), @@ -747,7 +753,8 @@ func TestCursor(t *testing.T) { ), want: pointer.CursorDefault, }, - {label: "add new input on top while inside", + { + label: "add new input on top while inside", cursors: []pointer.Cursor{pointer.CursorPointer, pointer.CursorCrosshair}, events: append( _at(50, 50), @@ -758,7 +765,8 @@ func TestCursor(t *testing.T) { ), want: pointer.CursorCrosshair, }, - {label: "remove input on top while inside", + { + label: "remove input on top while inside", cursors: []pointer.Cursor{pointer.CursorPointer}, events: append( _at(50, 50), @@ -1289,7 +1297,7 @@ func BenchmarkRouterAdd(b *testing.B) { handlerCount := i b.Run(fmt.Sprintf("%d-handlers", i), func(b *testing.B) { handlers := make([]event.Tag, handlerCount) - for i := 0; i < handlerCount; i++ { + for i := range handlerCount { h := new(int) *h = i handlers[i] = h @@ -1311,7 +1319,7 @@ func BenchmarkRouterAdd(b *testing.B) { r.Frame(&ops) b.ReportAllocs() b.ResetTimer() - for i := 0; i < b.N; i++ { + for b.Loop() { r.Queue( pointer.Event{ Kind: pointer.Move, diff --git a/io/input/router.go b/io/input/router.go index c18ae066..e5f73658 100644 --- a/io/input/router.go +++ b/io/input/router.go @@ -5,6 +5,7 @@ package input import ( "image" "io" + "slices" "strings" "time" @@ -302,7 +303,7 @@ func (q *Router) Event(filters ...event.Filter) (event.Event, bool) { } } if match { - change.events = append(change.events[:j], change.events[j+1:]...) + change.events = slices.Delete(change.events, j, j+1) // Fast forward state to last matched. q.collapseState(i) return evt.event, true diff --git a/io/input/router_test.go b/io/input/router_test.go index b8928829..05faf062 100644 --- a/io/input/router_test.go +++ b/io/input/router_test.go @@ -15,7 +15,7 @@ func TestNoFilterAllocs(t *testing.T) { s := r.Source() b.ReportAllocs() b.ResetTimer() - for i := 0; i < b.N; i++ { + for b.Loop() { s.Event(pointer.Filter{}) } }) diff --git a/io/input/semantic_test.go b/io/input/semantic_test.go index 21263293..88ee422d 100644 --- a/io/input/semantic_test.go +++ b/io/input/semantic_test.go @@ -125,7 +125,7 @@ func verifyTree(t *testing.T, parent SemanticID, n SemanticNode) { } func printTree(indent int, n SemanticNode) { - for i := 0; i < indent; i++ { + for range indent { fmt.Print("\t") } fmt.Printf("%d: %+v\n", n.ID, n.Desc) diff --git a/io/pointer/pointer.go b/io/pointer/pointer.go index 4cba66ec..9e389dea 100644 --- a/io/pointer/pointer.go +++ b/io/pointer/pointer.go @@ -43,8 +43,7 @@ type Event struct { // PassOp sets the pass-through mode. InputOps added while the pass-through // mode is set don't block events to siblings. -type PassOp struct { -} +type PassOp struct{} // PassStack represents a PassOp on the pass stack. type PassStack struct { diff --git a/layout/list.go b/layout/list.go index 3cd7cea4..091fb181 100644 --- a/layout/list.go +++ b/layout/list.go @@ -308,10 +308,6 @@ func (l *List) layout(ops *op.Ops, macro op.MacroOp) Dimensions { cross = (maxCross - sz.Y) / 2 } childSize := sz.X - min := pos - if min < 0 { - min = 0 - } pt := l.Axis.Convert(image.Pt(pos, cross)) trans := op.Offset(pt).Push(ops) child.call.Add(ops) diff --git a/layout/list_test.go b/layout/list_test.go index ad0163f0..4a2fe389 100644 --- a/layout/list_test.go +++ b/layout/list_test.go @@ -88,7 +88,8 @@ func TestListPosition(t *testing.T) { {label: "1 visible 0 hidden", num: 1, count: 1, last: 10}, {label: "2 visible 0 hidden", num: 2, count: 2}, {label: "2 visible 1 hidden", num: 3, count: 2}, - {label: "3 visible 0 hidden small scroll", num: 3, count: 3, offset: 5, last: -5, + { + label: "3 visible 0 hidden small scroll", num: 3, count: 3, offset: 5, last: -5, scroll: _s( pointer.Event{ Source: pointer.Mouse, @@ -107,8 +108,10 @@ func TestListPosition(t *testing.T) { Kind: pointer.Release, Position: f32.Pt(5, 0), }, - )}, - {label: "3 visible 0 hidden small scroll 2", num: 3, count: 3, offset: 3, last: -7, + ), + }, + { + label: "3 visible 0 hidden small scroll 2", num: 3, count: 3, offset: 3, last: -7, scroll: _s( pointer.Event{ Source: pointer.Mouse, @@ -127,8 +130,10 @@ func TestListPosition(t *testing.T) { Kind: pointer.Release, Position: f32.Pt(5, 0), }, - )}, - {label: "2 visible 1 hidden large scroll", num: 3, count: 2, first: 1, + ), + }, + { + label: "2 visible 1 hidden large scroll", num: 3, count: 2, first: 1, scroll: _s( pointer.Event{ Source: pointer.Mouse, @@ -147,7 +152,8 @@ func TestListPosition(t *testing.T) { Kind: pointer.Release, Position: f32.Pt(15, 0), }, - )}, + ), + }, } { t.Run(tc.label, func(t *testing.T) { gtx.Ops.Reset() diff --git a/layout/stack_test.go b/layout/stack_test.go index b7182894..cfdd27df 100644 --- a/layout/stack_test.go +++ b/layout/stack_test.go @@ -17,9 +17,8 @@ func BenchmarkStack(b *testing.B) { }, } b.ReportAllocs() - b.ResetTimer() - for i := 0; i < b.N; i++ { + for b.Loop() { gtx.Ops.Reset() Stack{}.Layout(gtx, @@ -41,9 +40,8 @@ func BenchmarkBackground(b *testing.B) { }, } b.ReportAllocs() - b.ResetTimer() - for i := 0; i < b.N; i++ { + for b.Loop() { gtx.Ops.Reset() Background{}.Layout(gtx, diff --git a/op/clip/clip.go b/op/clip/clip.go index d353d936..81b7861f 100644 --- a/op/clip/clip.go +++ b/op/clip/clip.go @@ -275,7 +275,7 @@ func (p *Path) QuadTo(ctrl, to f32.Point) { // negative clockwise. func (p *Path) ArcTo(f1, f2 f32.Point, angle float32) { m, segments := stroke.ArcTransform(p.pen, f1, f2, angle) - for i := 0; i < segments; i++ { + for range segments { p0 := p.pen p1 := m.Transform(p0) p2 := m.Transform(p1) diff --git a/op/paint/paint.go b/op/paint/paint.go index 1ccb3d93..e3afc939 100644 --- a/op/paint/paint.go +++ b/op/paint/paint.go @@ -35,7 +35,7 @@ type ImageOp struct { // handle is a key to uniquely identify this ImageOp // in a map of cached textures. - handle interface{} + handle any } // ColorOp sets the brush to a constant color. @@ -53,8 +53,7 @@ type LinearGradientOp struct { } // PaintOp fills the current clip area with the current brush. -type PaintOp struct { -} +type PaintOp struct{} // OpacityStack represents an opacity applied to all painting operations // until Pop is called. diff --git a/text/gotext.go b/text/gotext.go index d600b71a..be3f84d8 100644 --- a/text/gotext.go +++ b/text/gotext.go @@ -356,7 +356,7 @@ func (s *shaperImpl) splitBidi(input shaping.Input) []shaping.Input { if err != nil { return []shaping.Input{input} } - for i := 0; i < out.NumRuns(); i++ { + for i := range out.NumRuns() { currentInput := input run := out.Run(i) dir := run.Direction() @@ -685,7 +685,7 @@ func (s *shaperImpl) Shape(pathOps *op.Ops, gs []Glyph) clip.PathSpec { nargs = 3 } var args [3]f32.Point - for i := 0; i < nargs; i++ { + for i := range nargs { a := f32.Point{ X: fseg.Args[i].X * scaleFactor, Y: -fseg.Args[i].Y * scaleFactor, diff --git a/text/gotext_test.go b/text/gotext_test.go index 334114da..497f4730 100644 --- a/text/gotext_test.go +++ b/text/gotext_test.go @@ -126,7 +126,8 @@ func TestShapingAlignWidth(t *testing.T) { }, } { t.Run(tc.name, func(t *testing.T) { - lines := shaper.LayoutString(Parameters{PxPerEm: ppem, + lines := shaper.LayoutString(Parameters{ + PxPerEm: ppem, MinWidth: tc.minWidth, MaxWidth: tc.maxWidth, Locale: english, @@ -174,7 +175,6 @@ func TestNewlineSynthesis(t *testing.T) { }, } { t.Run(tc.name, func(t *testing.T) { - doc := shaper.LayoutRunes(Parameters{ PxPerEm: ppem, MaxWidth: 200, @@ -207,7 +207,6 @@ func TestNewlineSynthesis(t *testing.T) { } }) } - } // simpleGlyph returns a simple square glyph with the provided cluster diff --git a/text/lru_test.go b/text/lru_test.go index a7af3259..809b56e3 100644 --- a/text/lru_test.go +++ b/text/lru_test.go @@ -35,10 +35,10 @@ func TestPathLRU(t *testing.T) { } func testLRU(t *testing.T, put func(i int), get func(i int) bool) { - for i := 0; i < maxSize; i++ { + for i := range maxSize { put(i) } - for i := 0; i < maxSize; i++ { + for i := range maxSize { if !get(i) { t.Fatalf("key %d was evicted", i) } diff --git a/widget/editor.go b/widget/editor.go index 43c283be..46470a70 100644 --- a/widget/editor.go +++ b/widget/editor.go @@ -929,7 +929,7 @@ func (e *Editor) replace(start, end int, s string, addHistory bool) int { if addHistory { deleted := make([]rune, 0, replaceSize) readPos := e.text.ByteOffset(start) - for i := 0; i < replaceSize; i++ { + for range replaceSize { ru, s, _ := e.text.ReadRuneAt(int64(readPos)) readPos += int64(s) deleted = append(deleted, ru) @@ -1021,7 +1021,7 @@ func (e *Editor) deleteWord(distance int) (deletedRunes int) { return r } runes := 1 - for ii := 0; ii < words; ii++ { + for range words { r := next(runes) wantSpace := unicode.IsSpace(r) for r := next(runes); unicode.IsSpace(r) == wantSpace && !atEnd(runes); r = next(runes) { diff --git a/widget/editor_test.go b/widget/editor_test.go index ce43973a..cc8d7aec 100644 --- a/widget/editor_test.go +++ b/widget/editor_test.go @@ -992,7 +992,7 @@ func TestEditorSelectShortcuts(t *testing.T) { tFont := font.Font{} tFontSize := unit.Sp(10) tShaper := text.NewShaper(text.NoSystemFonts(), text.WithCollection(gofont.Collection())) - var tEditor = &Editor{ + tEditor := &Editor{ SingleLine: false, ReadOnly: true, } @@ -1255,7 +1255,7 @@ func TestNoFilterAllocs(t *testing.T) { } b.ReportAllocs() b.ResetTimer() - for i := 0; i < b.N; i++ { + for b.Loop() { e.Update(gtx) } }) diff --git a/widget/fit_test.go b/widget/fit_test.go index d5d78dc6..fe403904 100644 --- a/widget/fit_test.go +++ b/widget/fit_test.go @@ -31,7 +31,8 @@ func TestFit(t *testing.T) { Dims: image.Point{50, 200}, Scale: f32.Point{X: 1, Y: 1}, Result: image.Point{X: 50, Y: 100}, - }}, + }, + }, Contain: { { Dims: image.Point{50, 25}, @@ -41,7 +42,8 @@ func TestFit(t *testing.T) { Dims: image.Point{50, 200}, Scale: f32.Point{X: 0.5, Y: 0.5}, Result: image.Point{X: 25, Y: 100}, - }}, + }, + }, Cover: { { Dims: image.Point{50, 25}, @@ -51,7 +53,8 @@ func TestFit(t *testing.T) { Dims: image.Point{50, 200}, Scale: f32.Point{X: 2, Y: 2}, Result: image.Point{X: 100, Y: 100}, - }}, + }, + }, ScaleDown: { { Dims: image.Point{50, 25}, @@ -61,7 +64,8 @@ func TestFit(t *testing.T) { Dims: image.Point{50, 200}, Scale: f32.Point{X: 0.5, Y: 0.5}, Result: image.Point{X: 25, Y: 100}, - }}, + }, + }, Fill: { { Dims: image.Point{50, 25}, @@ -71,7 +75,8 @@ func TestFit(t *testing.T) { Dims: image.Point{50, 200}, Scale: f32.Point{X: 2, Y: 0.5}, Result: image.Point{X: 100, Y: 100}, - }}, + }, + }, } for fit, tests := range fittests { diff --git a/widget/index_test.go b/widget/index_test.go index 1bdb16a5..6424cfa0 100644 --- a/widget/index_test.go +++ b/widget/index_test.go @@ -73,10 +73,11 @@ func makeAccountingTestText(str string, fontSize, lineWidth int) (txt []text.Gly ltrFace, _ := opentype.Parse(goregular.TTF) rtlFace, _ := opentype.Parse(nsareg.TTF) - shaper := text.NewShaper(text.NoSystemFonts(), text.WithCollection([]font.FontFace{{ - Font: font.Font{Typeface: "LTR"}, - Face: ltrFace, - }, + shaper := text.NewShaper(text.NoSystemFonts(), text.WithCollection([]font.FontFace{ + { + Font: font.Font{Typeface: "LTR"}, + Face: ltrFace, + }, { Font: font.Font{Typeface: "RTL"}, Face: rtlFace, @@ -99,10 +100,11 @@ func getGlyphs(fontSize, minWidth, lineWidth int, align text.Alignment, str stri ltrFace, _ := opentype.Parse(goregular.TTF) rtlFace, _ := opentype.Parse(nsareg.TTF) - shaper := text.NewShaper(text.NoSystemFonts(), text.WithCollection([]font.FontFace{{ - Font: font.Font{Typeface: "LTR"}, - Face: ltrFace, - }, + shaper := text.NewShaper(text.NoSystemFonts(), text.WithCollection([]font.FontFace{ + { + Font: font.Font{Typeface: "LTR"}, + Face: ltrFace, + }, { Font: font.Font{Typeface: "RTL"}, Face: rtlFace, @@ -245,7 +247,7 @@ func TestIndexPositionWhitespace(t *testing.T) { if len(gi.positions) != len(tc.expected) { t.Errorf("expected %d positions, got %d", len(tc.expected), len(gi.positions)) } - for i := 0; i < min(len(gi.positions), len(tc.expected)); i++ { + for i := range min(len(gi.positions), len(tc.expected)) { actual := gi.positions[i] expected := tc.expected[i] if actual != expected { @@ -258,7 +260,6 @@ func TestIndexPositionWhitespace(t *testing.T) { } }) } - } // TestIndexPositionBidi tests whether the index correct generates cursor positions for @@ -312,7 +313,7 @@ func TestIndexPositionBidi(t *testing.T) { lastLine := 0 lastCol := -1 lastY := 0 - for i := 0; i < min(len(gi.positions), len(tc.expectedXs)); i++ { + for i := range min(len(gi.positions), len(tc.expectedXs)) { actualX := gi.positions[i].x expectedX := tc.expectedXs[i] if actualX != expectedX { @@ -538,7 +539,7 @@ func TestIndexPositionLines(t *testing.T) { if len(gi.lines) != len(tc.expectedLines) { t.Errorf("expected %d lines, got %d", len(tc.expectedLines), len(gi.lines)) } - for i := 0; i < min(len(gi.lines), len(tc.expectedLines)); i++ { + for i := range min(len(gi.lines), len(tc.expectedLines)) { actual := gi.lines[i] expected := tc.expectedLines[i] if actual != expected { @@ -623,7 +624,7 @@ func TestIndexPositionRunes(t *testing.T) { if len(gi.positions) != len(tc.expected) { t.Errorf("expected %d positions, got %d", len(tc.expected), len(gi.positions)) } - for i := 0; i < min(len(gi.positions), len(tc.expected)); i++ { + for i := range min(len(gi.positions), len(tc.expected)) { actual := gi.positions[i] expected := tc.expected[i] if expected.runes != actual.runes { @@ -646,6 +647,7 @@ func TestIndexPositionRunes(t *testing.T) { }) } } + func printPositions(t *testing.T, positions []combinedPos) { t.Helper() for i, p := range positions { @@ -720,7 +722,7 @@ func TestGraphemeReaderNext(t *testing.T) { if len(asRunes) != len(runes) { t.Errorf("expected %d runes, got %d", len(asRunes), len(runes)) } - for i := 0; i < max(len(asRunes), len(runes)); i++ { + for i := range max(len(asRunes), len(runes)) { if i < min(len(asRunes), len(runes)) { if runes[i] != asRunes[i] { t.Errorf("expected runes[%d]=%d, got %d", i, asRunes[i], runes[i]) @@ -734,6 +736,7 @@ func TestGraphemeReaderNext(t *testing.T) { }) } } + func TestGraphemeReaderGraphemes(t *testing.T) { latinDoc := bytes.NewReader([]byte(latinDocument)) arabicDoc := bytes.NewReader([]byte(arabicDocument)) @@ -787,7 +790,7 @@ func TestGraphemeReaderGraphemes(t *testing.T) { if len(asRunes)+1 < len(graphemes) { t.Errorf("expected <= %d graphemes, got %d", len(asRunes)+1, len(graphemes)) } - for i := 0; i < len(graphemes)-1; i++ { + for i := range len(graphemes) - 1 { if graphemes[i] >= graphemes[i+1] { t.Errorf("graphemes[%d](%d) >= graphemes[%d](%d)", i, graphemes[i], i+1, graphemes[i+1]) } @@ -795,6 +798,7 @@ func TestGraphemeReaderGraphemes(t *testing.T) { }) } } + func BenchmarkGraphemeReaderNext(b *testing.B) { latinDoc := bytes.NewReader([]byte(latinDocument)) arabicDoc := bytes.NewReader([]byte(arabicDocument)) @@ -831,7 +835,7 @@ func BenchmarkGraphemeReaderNext(b *testing.B) { var paragraph []rune = make([]rune, 4096) b.Run(tc.name, func(b *testing.B) { b.ResetTimer() - for i := 0; i < b.N; i++ { + for b.Loop() { pr.SetSource(tc.input) ok := true @@ -844,6 +848,7 @@ func BenchmarkGraphemeReaderNext(b *testing.B) { }) } } + func BenchmarkGraphemeReaderGraphemes(b *testing.B) { latinDoc := bytes.NewReader([]byte(latinDocument)) arabicDoc := bytes.NewReader([]byte(arabicDocument)) @@ -879,7 +884,7 @@ func BenchmarkGraphemeReaderGraphemes(b *testing.B) { } { b.Run(tc.name, func(b *testing.B) { b.ResetTimer() - for i := 0; i < b.N; i++ { + for b.Loop() { pr.SetSource(tc.input) for g := tc.read(); len(g) > 0; g = tc.read() { _ = g diff --git a/widget/text.go b/widget/text.go index 163caa57..8ddc5b28 100644 --- a/widget/text.go +++ b/widget/text.go @@ -717,7 +717,7 @@ func (e *textView) MoveWord(distance int, selAct selectionAction) { } return r } - for ii := 0; ii < words; ii++ { + for range words { for r := next(); unicode.IsSpace(r) && !atEnd(); r = next() { e.MoveCaret(direction, 0) caret = e.closestToRune(e.caret.start) diff --git a/widget/text_bench_test.go b/widget/text_bench_test.go index 34a81b71..28ef5fa6 100644 --- a/widget/text_bench_test.go +++ b/widget/text_bench_test.go @@ -92,7 +92,7 @@ func BenchmarkLabelStatic(b *testing.B) { runesStr := string(runes) l := Label{} b.ResetTimer() - for i := 0; i < b.N; i++ { + for b.Loop() { l.Layout(gtx, cache, font, fontSize, runesStr, op.CallOp{}) if render { win.Frame(gtx.Ops) @@ -124,7 +124,7 @@ func BenchmarkLabelDynamic(b *testing.B) { l := Label{} r := rand.New(rand.NewSource(42)) b.ResetTimer() - for i := 0; i < b.N; i++ { + for b.Loop() { // simulate a constantly changing string a := r.Intn(len(runes)) b := r.Intn(len(runes)) @@ -161,7 +161,7 @@ func BenchmarkEditorStatic(b *testing.B) { e := Editor{} e.SetText(runesStr) b.ResetTimer() - for i := 0; i < b.N; i++ { + for b.Loop() { e.Layout(gtx, cache, font, fontSize, op.CallOp{}, op.CallOp{}) if render { win.Frame(gtx.Ops) @@ -194,7 +194,7 @@ func BenchmarkEditorDynamic(b *testing.B) { e.SetText(string(runes)) r := rand.New(rand.NewSource(42)) b.ResetTimer() - for i := 0; i < b.N; i++ { + for b.Loop() { // simulate a constantly changing string a := r.Intn(e.Len()) b := r.Intn(e.Len())