github.com/razvanm/vanadium-go-1.3@v0.0.0-20160721203343-4a65068e5915/src/runtime/ppapi/graphics2D_nacl.go (about)

     1  // Copyright 2014 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 ppapi
     6  
     7  import (
     8  	"errors"
     9  )
    10  
    11  // Graphics2D represents a 2D graphics context.  The context must be bound to an
    12  // Instance, using BindGraphics2D(), for the drawing to be visible.
    13  type Graphics2D struct {
    14  	Resource
    15  }
    16  
    17  var (
    18  	errBindFailed                = errors.New("graphics bind failed")
    19  	errGraphics2DCreateFailed    = errors.New("graphics2D creation failed")
    20  	errGraphics2DContext         = errors.New("graphics2D context error")
    21  	errGraphics2DOperationFailed = errors.New("graphics2D operation failed")
    22  )
    23  
    24  // NewGraphics2D returns a new Graphics2D instance.
    25  func (inst Instance) NewGraphics2D(size Size, isAlwaysOpaque bool) (g Graphics2D, err error) {
    26  	rid := ppb_graphics2d_create(inst.id, &size, toPPBool(isAlwaysOpaque))
    27  	if rid == 0 {
    28  		err = errGraphics2DCreateFailed
    29  		return
    30  	}
    31  	g.id = rid
    32  	return
    33  }
    34  
    35  // BindGraphics2D binds the Graphics2D context to the Instance.
    36  func (inst Instance) BindGraphics2D(g Graphics2D) error {
    37  	b := ppb_instance_bind_graphics(inst.id, g.id)
    38  	if b == 0 {
    39  		return errBindFailed
    40  	}
    41  	return nil
    42  }
    43  
    44  // Describe returns the size and opacity of the graphics 2D context.
    45  func (g Graphics2D) Describe() (size Size, isAlwaysOpaque bool, err error) {
    46  	var b pp_Bool
    47  	ok := ppb_graphics2d_describe(g.id, &size, &b)
    48  	if ok == 0 {
    49  		err = errGraphics2DContext
    50  		return
    51  	}
    52  	isAlwaysOpaque = b != 0
    53  	err = nil
    54  	return
    55  }
    56  
    57  // Scroll enqueues a scroll of the context's backing store. This function has no
    58  // effect until you call Flush(). The data within the provided clipping
    59  // rectangle will be shifted by (dx, dy) pixels.
    60  //
    61  // This function will result in some exposed region which will have undefined
    62  // contents. The module should call PaintImageData() on these exposed regions to
    63  // give the correct contents.
    64  //
    65  // The scroll can be larger than the area of the clipping rectangle, which means
    66  // the current image will be scrolled out of the rectangle. This scenario is not
    67  // an error but will result in a no-op.
    68  func (g Graphics2D) Scroll(clipRect Rect, amount Point) {
    69  	ppb_graphics2d_scroll(g.id, &clipRect, &amount)
    70  }
    71  
    72  // GetScale returns the scale factor that will be applied when painting the
    73  // graphics context onto the output device.
    74  func (g Graphics2D) GetScale() float32 {
    75  	return ppb_graphics2d_get_scale(g.id)
    76  }
    77  
    78  // SetScale sets the scale factor that will be applied when painting the
    79  // graphics context onto the output device.
    80  //
    81  // Typically, if rendering at device resolution is desired, the context would be
    82  // created with the width and height scaled up by the view's GetDeviceScale and
    83  // SetScale called with a scale of 1.0 / GetDeviceScale(). For example, if the
    84  // view resource passed to DidChangeView has a rectangle of (w=200, h=100) and a
    85  // device scale of 2.0, one would call Create with a size of (w=400, h=200) and
    86  // then call SetScale with 0.5. One would then treat each pixel in the context
    87  // as a single device pixel.
    88  func (g Graphics2D) SetScale(scale float32) error {
    89  	b := ppb_graphics2d_set_scale(g.id, scale)
    90  	if b == ppFalse {
    91  		return errGraphics2DOperationFailed
    92  	}
    93  	return nil
    94  }
    95  
    96  // PaintImageData() enqueues a paint of the given image into the context.
    97  //
    98  // This function has no effect until you call Flush() As a result, what counts
    99  // is the contents of the bitmap when you call Flush(), not when you call this
   100  // function.
   101  //
   102  // The provided image will be placed at top_left from the top left of the
   103  // context's internal backing store. Then the pixels contained in src_rect will
   104  // be copied into the backing store. This means that the rectangle being painted
   105  // will be at src_rect offset by top_left.
   106  //
   107  // The src_rect is specified in the coordinate system of the image being
   108  // painted, not the context. For the common case of copying the entire image,
   109  // you may specify an empty src_rect.
   110  //
   111  // The painted area of the source bitmap must fall entirely within the
   112  // context. Attempting to paint outside of the context will result in an
   113  // error. However, the source bitmap may fall outside the context, as long as
   114  // the src_rect subset of it falls entirely within the context.
   115  //
   116  // There are two methods most modules will use for painting. The first method is
   117  // to generate a new ImageData and then paint it. In this case, you'll set the
   118  // location of your painting to top_left and set src_rect to NULL. The second is
   119  // that you're generating small invalid regions out of a larger bitmap
   120  // representing your entire instance. In this case, you would set the location
   121  // of your image to (0,0) and then set src_rect to the pixels you changed.
   122  func (g Graphics2D) PaintImageData(data ImageData, topLeft Point, src *Rect) {
   123  	ppb_graphics2d_paint_image_data(g.id, data.id, &topLeft, src)
   124  }
   125  
   126  // ReplaceContents provides a slightly more efficient way to paint the entire
   127  // module's image.
   128  //
   129  // Normally, calling PaintImageData() requires that the browser copy the pixels
   130  // out of the image and into the graphics context's backing store. This function
   131  // replaces the graphics context's backing store with the given image, avoiding
   132  // the copy.
   133  //
   134  // The new image must be the exact same size as this graphics context. If the
   135  // new image uses a different image format than the browser's native bitmap
   136  // format (use PPB_ImageData.GetNativeImageDataFormat() to retrieve the format),
   137  // then a conversion will be done inside the browser which may slow the
   138  // performance a little bit.
   139  //
   140  // Note: The new image will not be painted until you call Flush().
   141  //
   142  // After this call, you should take care to release your references to the
   143  // image. If you paint to the image after ReplaceContents(), there is the
   144  // possibility of significant painting artifacts because the page might use
   145  // partially-rendered data when copying out of the backing store.
   146  //
   147  // In the case of an animation, you will want to allocate a new image for the
   148  // next frame. It is best if you wait until the flush callback has executed
   149  // before allocating this bitmap. This gives the browser the option of caching
   150  // the previous backing store and handing it back to you (assuming the sizes
   151  // match). In the optimal case, this means no bitmaps are allocated during the
   152  // animation, and the backing store and "front buffer" (which the plugin is
   153  // painting into) are just being swapped back and forth.
   154  func (g Graphics2D) ReplaceContents(data ImageData) {
   155  	ppb_graphics2d_replace_contents(g.id, data.id)
   156  }
   157  
   158  // Flush flushes any enqueued paint, scroll, and replace commands to the
   159  // backing store.
   160  //
   161  // This function actually executes the updates, and causes a repaint of the
   162  // webpage, assuming this graphics context is bound to a module instance.
   163  //
   164  // Flush() runs in asynchronous mode. Specify a callback function and the
   165  // argument for that callback function. The callback function will be executed
   166  // on the calling thread when the image has been painted to the screen. While
   167  // you are waiting for a flush callback, additional calls to Flush() will fail.
   168  //
   169  // Because the callback is executed (or thread unblocked) only when the
   170  // instance's image is actually on the screen, this function provides a way to
   171  // rate limit animations. By waiting until the image is on the screen before
   172  // painting the next frame, you can ensure you're not flushing 2D graphics
   173  // faster than the screen can be updated.
   174  //
   175  // Unbound contexts If the context is not bound to a module instance, you will
   176  // still get a callback. The callback will execute after Flush() returns to
   177  // avoid reentrancy. The callback will not wait until anything is painted to the
   178  // screen because there will be nothing on the screen. The timing of this
   179  // callback is not guaranteed and may be deprioritized by the browser because it
   180  // is not affecting the user experience.
   181  //
   182  // Off-screen instances If the context is bound to an instance that is currently
   183  // not visible (for example, scrolled out of view) it will behave like the
   184  // "unbound context" case.
   185  //
   186  // Detaching a context If you detach a context from a module instance, any
   187  // pending flush callbacks will be converted into the "unbound context" case.
   188  //
   189  // Released contexts A callback may or may not get called even if you have
   190  // released all of your references to the context. This scenario can occur if
   191  // there are internal references to the context suggesting it has not been
   192  // internally destroyed (for example, if it is still bound to an instance) or
   193  // due to other implementation details. As a result, you should be careful to
   194  // check that flush callbacks are for the context you expect and that you're
   195  // capable of handling callbacks for unreferenced contexts.
   196  //
   197  // Shutdown If a module instance is removed when a flush is pending, the
   198  // callback will not be executed.
   199  func (g Graphics2D) Flush() error {
   200  	code := ppb_graphics2d_flush(g.id, ppNullCompletionCallback)
   201  	return decodeError(Error(code))
   202  }