diff --git a/browsercheck/check.go b/browsercheck/check.go index 77860d9..b002bbd 100644 --- a/browsercheck/check.go +++ b/browsercheck/check.go @@ -100,13 +100,21 @@ func check(ctx context.Context, c *conn, page, sample, shot, dl string) error { if err != nil { return false, err } - return v.Hash != empty.Hash && v.Dark > empty.Dark, nil + // The canvas changed, more of it is drawn on than before, and there is + // more ink than the empty workbench's own furniture. + // + // It used to ask for more NEARLY BLACK pixels, and a scanned page has + // almost none: its ink is grey once it has been scaled to fit, and it + // covers the strip and the borders that were the dark pixels being + // counted. A real scanned document therefore read as never having + // arrived, on a page that was drawn correctly. + return v.Hash != empty.Hash && v.N > empty.N && v.Ink > empty.Ink, nil }); err != nil { say(c) return fmt.Errorf("the document never appeared on the canvas: %w", err) } withDoc, _ := look(ctx, c, sid) - fmt.Printf("document shown: %d pixels drawn, %d of them dark\n", withDoc.N, withDoc.Dark) + fmt.Printf("document shown: %d pixels drawn, %d of them ink\n", withDoc.N, withDoc.Ink) if err := screenshot(ctx, c, sid, shot); err != nil { return err @@ -359,8 +367,14 @@ func say(c *conn) { // canvas is what the tab actually has on its canvas. type canvas struct { - N int `json:"n"` + N int `json:"n"` + // Dark is how many pixels are nearly black. It tells a lit control from an + // unlit one, which is what it is for. Dark int `json:"dark"` + // Ink is how many pixels are dark the way text is dark. A scanned page + // scaled to fit a window is grey, not black: the same page counts 1805 + // pixels this way and 9 the other. + Ink int `json:"ink"` Hash int `json:"hash"` } @@ -384,13 +398,18 @@ func lookIn(ctx context.Context, c *conn, sid string, from, to float64) (canvas, const y0 = Math.floor(c.height * 0.07), y1 = Math.floor(c.height * 0.95); const d = c.getContext('2d').getImageData(x0, y0, x1 - x0, y1 - y0).data; const r0 = d[0], g0 = d[1], b0 = d[2]; - let n = 0, dark = 0, hash = 0; + let n = 0, dark = 0, ink = 0, hash = 0; for (let i = 0; i < d.length; i += 4) { if (d[i] !== r0 || d[i+1] !== g0 || d[i+2] !== b0) n++; if (d[i] + d[i+1] + d[i+2] < 240) dark++; + // Ink, as opposed to nearly black. Scanned text that has been scaled + // down to fit a window is grey: the same page counts 1805 pixels this + // way and 9 the other, so which threshold is used decides whether a + // scanned document is seen to arrive at all. + if ((d[i] * 299 + d[i+1] * 587 + d[i+2] * 114) / 1000 < 128) ink++; hash = (hash * 31 + d[i] + d[i+1] * 3 + d[i+2] * 7) | 0; } - return JSON.stringify({n, dark, hash}); + return JSON.stringify({n, dark, ink, hash}); })()`, from, to) var out canvas s, err := eval(ctx, c, sid, js) diff --git a/go.mod b/go.mod index b254f76..a8d5639 100644 --- a/go.mod +++ b/go.mod @@ -3,18 +3,20 @@ module github.com/go-pdfkit/app go 1.26.4 require ( - github.com/go-gfx/gfx v0.10.0 + github.com/go-gfx/gfx v0.15.0 github.com/go-pdfkit/extract v0.3.0 github.com/go-pdfkit/forms v0.2.2 - github.com/go-pdfkit/ops v0.7.1 + github.com/go-pdfkit/ops v0.7.2 github.com/go-pdfkit/reader v0.6.0 - github.com/go-pdfkit/render v0.11.0 + github.com/go-pdfkit/render v0.19.0 github.com/go-widgets/painter v0.11.0 github.com/go-widgets/toolkit v0.277.0 github.com/go-widgets/webcanvas v0.1.0 ) require ( + github.com/ajroetker/go-highway v0.0.4 // indirect + github.com/ajroetker/go-jpeg2000 v0.0.2 // indirect github.com/andybalholm/brotli v1.2.2 // indirect github.com/coder/websocket v1.8.15 // indirect github.com/go-crdt/collab v0.25.0 // indirect @@ -28,6 +30,9 @@ require ( github.com/go-richdoc/richdoc v0.2.0 // indirect github.com/go-typeset/bidi v0.3.0 // indirect github.com/go-widgets/mvvm v0.5.0 // indirect + github.com/sergeymakinen/go-bmp v1.0.0 // indirect + github.com/sergeymakinen/go-ico v1.0.0 // indirect + github.com/tannevaled/gobig2 v0.1.0 // indirect golang.org/x/image v0.45.0 // indirect golang.org/x/net v0.49.0 // indirect golang.org/x/sys v0.47.0 // indirect diff --git a/go.sum b/go.sum index 0acf603..00eb4e9 100644 --- a/go.sum +++ b/go.sum @@ -1,3 +1,7 @@ +github.com/ajroetker/go-highway v0.0.4 h1:RDQo+9OhTXI6BFctLo+5gYpHNbb92VYJ0ObnR4l6xAQ= +github.com/ajroetker/go-highway v0.0.4/go.mod h1:C/zYPNSSpOaraejY89FUTZTyQNEhi5+rEbU0LjlqJeU= +github.com/ajroetker/go-jpeg2000 v0.0.2 h1:ni8brffZrci4Kacx3nM5d92ipmTDfak84KgHYi6IxFw= +github.com/ajroetker/go-jpeg2000 v0.0.2/go.mod h1:7ld88W47lZy0x8gRQesRGAonDPOpr6ev8rckjCAfbzE= github.com/andybalholm/brotli v1.2.2 h1:HzTuoo2ErYQqf5qvcJInB8uvqSVxRttzkFexPWtnceM= github.com/andybalholm/brotli v1.2.2/go.mod h1:rzTDkvFWvIrjDXZHkuS16NPggd91W3kUSvPlQ1pLaKY= github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs= @@ -8,8 +12,8 @@ github.com/go-crdt/collab v0.25.0 h1:xO/cZq41GvsCyPOw+sdldCu2r3lDbMK1N0GgN6D9+Ss github.com/go-crdt/collab v0.25.0/go.mod h1:eYhMwHjmRyN5zMk/IBwBsTe3ZxqHuSCvNx3TdVTpYHg= github.com/go-crdt/crdt v0.31.0 h1:CTi+lo0bjsJv3F09CR/AdILQtWEWmzbDQ+S/6HNBOMU= github.com/go-crdt/crdt v0.31.0/go.mod h1:vbfvns9B9FUaMi2sPKzMYttKmbxfgO7EK3Yu82SrlYw= -github.com/go-gfx/gfx v0.10.0 h1:3AqOO8TZph6/U8+ejJxYkCZ+wzddxAbZ7fxi6TvGop4= -github.com/go-gfx/gfx v0.10.0/go.mod h1:bFt/MWyYWRU3Ic9IaB8XOC9KLMMHRRmahMk4FaIGK7g= +github.com/go-gfx/gfx v0.15.0 h1:ol+4uqUTq8s23cGSjfbEHciTxkrZ7kTrpUuAPPz4XuY= +github.com/go-gfx/gfx v0.15.0/go.mod h1:VAK6hgCgkhT3j3ek2K7G8zDfkCPD3RCF45UbcRlCV8Q= github.com/go-iconoir/iconoir v0.2.0 h1:2ANqG6gkvHMoCtpNgNhSeOsuGMnlWQ+Sl43EndujIC0= github.com/go-iconoir/iconoir v0.2.0/go.mod h1:BrOQ68YO5BMsF7y+/nht4shbgjVfh9CxBoQF35eNosw= github.com/go-images/images v0.0.0-20260811115337-bc5d586f8e38 h1:p+DjIujiwUvBiyD0oS9SUatf3pMKo0GpcA4p/Kyv7d8= @@ -28,14 +32,14 @@ github.com/go-pdfkit/extract v0.3.0 h1:w1ansrvMNqd+Hy1p5fo1orh6hM8meb+xCNKNap/7o github.com/go-pdfkit/extract v0.3.0/go.mod h1:EOWOcx3o0HDC3ryCMoE9pwNIb3mwVmnXBSpTRfO1VdY= github.com/go-pdfkit/forms v0.2.2 h1:tGnENs09LBUBppSrH0dGenV8KCQcbngsi+OatWID90Y= github.com/go-pdfkit/forms v0.2.2/go.mod h1:dQ4FzO6qF7RJh6oEa0dkgL0i8hKBmm/e7hj4XC56h5Q= -github.com/go-pdfkit/ops v0.7.1 h1:JkjJOj4/x60VJpjGZgFTc950AE9hHUYBH9UlwJv3IzM= -github.com/go-pdfkit/ops v0.7.1/go.mod h1:rA+hZHtK3tpZW0j5Sz3sLBHMhbv3scPLI/k8Xij1r+U= +github.com/go-pdfkit/ops v0.7.2 h1:E1vLf+BcmuQuE9tlZ1dYCaiCsRpDEw9otOCVTjp90bY= +github.com/go-pdfkit/ops v0.7.2/go.mod h1:12bC9BoH7ru3OoOC52OjNMC+ti92M8Vrfd8NeRby2XE= github.com/go-pdfkit/pdffont v0.3.1 h1:+K7opHGRERDZ5EMkA12s1GT48t8GpncArhnyzyc5bxU= github.com/go-pdfkit/pdffont v0.3.1/go.mod h1:eFJ/7t9AvcX76KY5qNJMMKetz8hUUUdVM1qSWLi3S1g= github.com/go-pdfkit/reader v0.6.0 h1:KAabNOYUcTlZlNBTbG9bEhWP1NiZhjuhzUdavdTdfes= github.com/go-pdfkit/reader v0.6.0/go.mod h1:fQFOVfCMUui1AdvD4qhimdyvvNr9KvvJ1S7IuKZjyV8= -github.com/go-pdfkit/render v0.11.0 h1:z05asCKb8Bn/1JMU0r5KwqP5DiFkk0jJR3bVKGH4qj8= -github.com/go-pdfkit/render v0.11.0/go.mod h1:9b1LBmvHdZJ8+ACXA8XNUXWSOtNM+lkiOAFSiWRADpQ= +github.com/go-pdfkit/render v0.19.0 h1:BMyxO/mjUYo6bB7UKZHfFuyb3TDFnlJ1VT4i1aBUe/c= +github.com/go-pdfkit/render v0.19.0/go.mod h1:DrVmFaVDRM0qnzF7ZqWGZh4qPMSm7AO0DZaT6LVRd2A= github.com/go-richdoc/richdoc v0.2.0 h1:z9cLox9MoInZL6fIlweMzgDT/VqgnB2ZucSIEaRFglY= github.com/go-richdoc/richdoc v0.2.0/go.mod h1:aCX8ulqg5CoKqSWgWeEWul1Oj0d2VxQeaQNI0+jsm7c= github.com/go-typeset/bidi v0.3.0 h1:4fjGjejvjE2LzLNzY4si8PkVO321NcsKIiANhWT3jF4= @@ -56,6 +60,12 @@ github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/grpc-transports/websocket v0.2.0 h1:n4lN066PPcVTvTfLdwa84gfNiAzvS9k4SSQ1yWuG3+g= github.com/grpc-transports/websocket v0.2.0/go.mod h1:2z7Qy11qgPaGDfqzImOt0iyLwH0wjfsvaiidCIIpzgg= +github.com/sergeymakinen/go-bmp v1.0.0 h1:SdGTzp9WvCV0A1V0mBeaS7kQAwNLdVJbmHlqNWq0R+M= +github.com/sergeymakinen/go-bmp v1.0.0/go.mod h1:/mxlAQZRLxSvJFNIEGGLBE/m40f3ZnUifpgVDlcUIEY= +github.com/sergeymakinen/go-ico v1.0.0 h1:uL3khgvKkY6WfAetA+RqsguClBuu7HpvBB/nq/Jvr80= +github.com/sergeymakinen/go-ico v1.0.0/go.mod h1:wQ47mTczswBO5F0NoDt7O0IXgnV4Xy3ojrroMQzyhUk= +github.com/tannevaled/gobig2 v0.1.0 h1:9PdMvmnmYQURlUF40zt8t35Wnrz3KhZrwfxgCMvQc04= +github.com/tannevaled/gobig2 v0.1.0/go.mod h1:X0S1H+N35kg6zYgVYRqGMsGj3C35zs+iA2r1MXyPcV4= github.com/xyproto/randomstring v1.0.5 h1:YtlWPoRdgMu3NZtP45drfy1GKoojuR7hmRcnhZqKjWU= github.com/xyproto/randomstring v1.0.5/go.mod h1:rgmS5DeNXLivK7YprL0pY+lTuhNQW3iGxZ18UQApw/E= go.opentelemetry.io/auto/sdk v1.2.1 h1:jXsnJ4Lmnqd11kwkBV2LgLoFMZKizbCi5fNZ/ipaZ64=