github.com/graybobo/golang.org-package-offline-cache@v0.0.0-20200626051047-6608995c132f/x/exp/shiny/screen/screen.go (about) 1 // Copyright 2015 The Go Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 // Package screen provides interfaces for portable two-dimensional graphics and 6 // input events. 7 // 8 // Screens are not created directly. Instead, driver packages provide access to 9 // the screen through a Main function that is designed to be called by the 10 // program's main function. The golang.org/x/exp/shiny/driver package provides 11 // the default driver for the system, such as the X11 driver for desktop Linux, 12 // but other drivers, such as the OpenGL driver, can be explicitly invoked by 13 // calling that driver's Main function. To use the default driver: 14 // 15 // package main 16 // 17 // import ( 18 // "golang.org/x/exp/shiny/driver" 19 // "golang.org/x/exp/shiny/screen" 20 // ) 21 // 22 // func main() { 23 // driver.Main(func(s screen.Screen) { 24 // w, err := s.NewWindow(nil) 25 // if err != nil { 26 // handleError(err) 27 // return 28 // } 29 // for e := range w.Events() { 30 // handleEvent(e) 31 // } 32 // }) 33 // } 34 package screen 35 36 import ( 37 "image" 38 "image/color" 39 "image/draw" 40 41 "golang.org/x/image/math/f64" 42 ) 43 44 // TODO: specify image format (Alpha or Gray, not just RGBA) for NewBuffer 45 // and/or NewTexture? 46 47 // Screen creates Buffers, Textures and Windows. 48 type Screen interface { 49 // NewBuffer returns a new Buffer for this screen. 50 NewBuffer(size image.Point) (Buffer, error) 51 52 // NewTexture returns a new Texture for this screen. 53 NewTexture(size image.Point) (Texture, error) 54 55 // NewWindow returns a new Window for this screen. 56 NewWindow(opts *NewWindowOptions) (Window, error) 57 } 58 59 // TODO: rename Buffer to Image, to be less confusing with a Window's back and 60 // front buffers. 61 62 // Buffer is an in-memory pixel buffer. Its pixels can be modified by any Go 63 // code that takes an *image.RGBA, such as the standard library's image/draw 64 // package. 65 // 66 // To see a Buffer's contents on a screen, upload it to a Texture (and then 67 // draw the Texture on a Window) or upload it directly to a Window. 68 // 69 // When specifying a sub-Buffer via Upload, a Buffer's top-left pixel is always 70 // (0, 0) in its own coordinate space. 71 type Buffer interface { 72 // Release releases the Buffer's resources, after all pending uploads and 73 // draws resolve. The behavior of the Buffer after Release is undefined. 74 Release() 75 76 // Size returns the size of the Buffer's image. 77 Size() image.Point 78 79 // Bounds returns the bounds of the Buffer's image. It is equal to 80 // image.Rectangle{Max: b.Size()}. 81 Bounds() image.Rectangle 82 83 // RGBA returns the pixel buffer as an *image.RGBA. 84 // 85 // Its contents should not be accessed while the Buffer is uploading. 86 RGBA() *image.RGBA 87 } 88 89 // Texture is a pixel buffer, but not one that is directly accessible as a 90 // []byte. Conceptually, it could live on a GPU, in another process or even be 91 // across a network, instead of on a CPU in this process. 92 // 93 // Buffers can be uploaded to Textures, and Textures can be drawn on Windows. 94 // 95 // When specifying a sub-Texture via Draw, a Texture's top-left pixel is always 96 // (0, 0) in its own coordinate space. 97 type Texture interface { 98 // Release releases the Texture's resources, after all pending uploads and 99 // draws resolve. The behavior of the Texture after Release is undefined. 100 Release() 101 102 // Size returns the size of the Texture's image. 103 Size() image.Point 104 105 // Bounds returns the bounds of the Texture's image. It is equal to 106 // image.Rectangle{Max: t.Size()}. 107 Bounds() image.Rectangle 108 109 Uploader 110 111 // TODO: also implement Drawer? If so, merge the Uploader and Drawer 112 // interfaces?? 113 } 114 115 // Window is a top-level, double-buffered GUI window. 116 type Window interface { 117 // Release closes the window and its event channel. 118 Release() 119 120 // Events returns the window's event channel, which carries key, mouse, 121 // paint and other events. 122 // 123 // TODO: define and describe these events. 124 Events() <-chan interface{} 125 126 // Send sends an event to the window. 127 Send(event interface{}) 128 129 Uploader 130 131 Drawer 132 133 // Publish flushes any pending Upload and Draw calls to the window, and 134 // swaps the back buffer to the front. 135 Publish() PublishResult 136 } 137 138 // PublishResult is the result of an Window.Publish call. 139 type PublishResult struct { 140 // BackBufferPreserved is whether the contents of the back buffer was 141 // preserved. If false, the contents are undefined. 142 BackBufferPreserved bool 143 } 144 145 // NewWindowOptions are optional arguments to NewWindow. 146 type NewWindowOptions struct { 147 // Width and Height specify the dimensions of the new window. If Width 148 // or Height are zero, a driver-dependent default will be used for each 149 // zero value dimension. 150 Width, Height int 151 152 // TODO: fullscreen, title, icon, cursorHidden? 153 } 154 155 // Uploader is something you can upload a Buffer to. 156 type Uploader interface { 157 // Upload uploads the sub-Buffer defined by src and sr to the destination 158 // (the method receiver), such that sr.Min in src-space aligns with dp in 159 // dst-space. The destination's contents are overwritten; the draw operator 160 // is implicitly draw.Src. 161 // 162 // It is valid to upload a Buffer while another upload of the same Buffer 163 // is in progress, but a Buffer's image.RGBA pixel contents should not be 164 // accessed while it is uploading. A Buffer is re-usable, in that its pixel 165 // contents can be further modified, once all outstanding calls to Upload 166 // have returned. 167 // 168 // When uploading to a Window, there will not be any visible effect until 169 // Publish is called. 170 Upload(dp image.Point, src Buffer, sr image.Rectangle) 171 172 // Fill fills that part of the destination (the method receiver) defined by 173 // dr with the given color. 174 // 175 // When filling a Window, there will not be any visible effect until 176 // Publish is called. 177 Fill(dr image.Rectangle, src color.Color, op draw.Op) 178 } 179 180 // TODO: have a Downloader interface? Not every graphical app needs to be 181 // interactive or involve a window. You could use the GPU for hardware- 182 // accelerated image manipulation: upload a buffer, do some texture ops, then 183 // download the result. 184 185 // Drawer is something you can draw Textures on. 186 type Drawer interface { 187 // Draw draws the sub-Texture defined by src and sr to the destination (the 188 // method receiver). src2dst defines how to transform src coordinates to 189 // dst coordinates. For example, if src2dst is the matrix 190 // 191 // m00 m01 m02 192 // m10 m11 m12 193 // 194 // then the src-space point (sx, sy) maps to the dst-space point 195 // (m00*sx + m01*sy + m02, m10*sx + m11*sy + m12). 196 // 197 // When drawing on a Window, there will not be any visible effect until 198 // Publish is called. 199 Draw(src2dst f64.Aff3, src Texture, sr image.Rectangle, op draw.Op, opts *DrawOptions) 200 } 201 202 // Copy copies the sub-Texture defined by src and sr to dst, such that sr.Min 203 // in src-space aligns with dp in dst-space. 204 // 205 // When drawing on a Window, there will not be any visible effect until Publish 206 // is called. 207 func Copy(dst Drawer, dp image.Point, src Texture, sr image.Rectangle, op draw.Op, opts *DrawOptions) { 208 dst.Draw(f64.Aff3{ 209 1, 0, float64(dp.X - sr.Min.X), 210 0, 1, float64(dp.Y - sr.Min.Y), 211 }, src, sr, op, opts) 212 } 213 214 // Scale scales the sub-Texture defined by src and sr to dst, such that sr in 215 // src-space is mapped to dr in dst-space. 216 // 217 // When drawing on a Window, there will not be any visible effect until Publish 218 // is called. 219 func Scale(dst Drawer, dr image.Rectangle, src Texture, sr image.Rectangle, op draw.Op, opts *DrawOptions) { 220 rx := float64(dr.Dx()) / float64(sr.Dx()) 221 ry := float64(dr.Dy()) / float64(sr.Dy()) 222 dst.Draw(f64.Aff3{ 223 rx, 0, float64(dr.Min.X) - rx*float64(sr.Min.X), 224 0, ry, float64(dr.Min.Y) - ry*float64(sr.Min.Y), 225 }, src, sr, op, opts) 226 } 227 228 // These draw.Op constants are provided so that users of this package don't 229 // have to explicitly import "image/draw". 230 const ( 231 Over = draw.Over 232 Src = draw.Src 233 ) 234 235 // DrawOptions are optional arguments to Draw. 236 type DrawOptions struct { 237 // TODO: transparency in [0x0000, 0xffff]? 238 // TODO: scaler (nearest neighbor vs linear)? 239 }