/* Copyright (c) 2012 The Chromium Authors. All rights reserved.
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */

/**
 * Defines the <code>PPB_Graphics2D</code> struct representing a 2D graphics
 * context within the browser.
 */

[generate_thunk]

label Chrome {
  M14 = 1.0,
  M27 = 1.1,
  M52 = 1.2
};

/**
 * <code>PPB_Graphics2D</code> defines the interface for a 2D graphics context.
 */
[macro="PPB_GRAPHICS_2D_INTERFACE"]
interface PPB_Graphics2D {
  /**
   * Create() creates a 2D graphics context. The returned graphics context will
   * not be bound to the module instance on creation (call BindGraphics() on
   * the module instance to bind the returned graphics context to the module
   * instance).
   *
   * @param[in] instance The module instance.
   * @param[in] size The size of the graphic context.
   * @param[in] is_always_opaque Set the <code>is_always_opaque</code> flag to
   * <code>PP_TRUE</code> if you know that you will be painting only opaque
   * data to this context. This option will disable blending when compositing
   * the module with the web page, which might give higher performance on some
   * computers.
   *
   * If you set <code>is_always_opaque</code>, your alpha channel should always
   * be set to 0xFF or there may be painting artifacts. The alpha values
   * overwrite the destination alpha values without blending when
   * <code>is_always_opaque</code> is true.
   *
   * @return A <code>PP_Resource</code> containing the 2D graphics context if
   * successful or 0 if unsuccessful.
   */
  PP_Resource Create(
      [in] PP_Instance instance,
      [in] PP_Size size,
      [in] PP_Bool is_always_opaque);

  /**
   * IsGraphics2D() determines if the given resource is a valid
   * <code>Graphics2D</code>.
   *
   * @param[in] resource A <code>Graphics2D</code> context resource.
   *
   * @return PP_TRUE if the given resource is a valid <code>Graphics2D</code>,
   * <code>PP_FALSE</code> if it is an invalid resource or is a resource of
   * another type.
   */
  PP_Bool IsGraphics2D(
      [in] PP_Resource resource);

  /**
   * Describe() retrieves the configuration for the given graphics context,
   * filling the given values (which must not be <code>NULL</code>).
   *
   * @param[in] resource The 2D Graphics resource.
   * @param[in,out] size The size of the 2D graphics context in the browser.
   * @param[in,out] is_always_opaque Identifies whether only opaque data
   * will be painted.
   *
   * @return Returns <code>PP_TRUE</code> on success or <code>PP_FALSE</code> if
   * the resource is invalid. The output parameters will be set to 0 on a
   * <code>PP_FALSE</code>.
   */
  [always_set_output_parameters]
  PP_Bool Describe(
      [in] PP_Resource graphics_2d,
      [out] PP_Size size,
      [out] PP_Bool is_always_opaque);

  /**
   * PaintImageData() enqueues a paint of the given image into the context.
   * This function has no effect until you call Flush() As a result, what
   * counts is the contents of the bitmap when you call Flush(), not when
   * you call this function.
   *
   * The provided image will be placed at <code>top_left</code> from the top
   *  left of the context's internal backing store. Then the pixels contained
   * in <code>src_rect</code> will be copied into the backing store. This
   * means that the rectangle being painted will be at <code>src_rect</code>
   * offset by <code>top_left</code>.
   *
   * The <code>src_rect</code> is specified in the coordinate system of the
   * image being painted, not the context. For the common case of copying the
   * entire image, you may specify an empty <code>src_rect</code>.
   *
   * The painted area of the source bitmap must fall entirely within the
   * context. Attempting to paint outside of the context will result in an
   * error. However, the source bitmap may fall outside the context, as long
   * as the <code>src_rect</code> subset of it falls entirely within the
   * context.
   *
   * There are two methods most modules will use for painting. The first
   * method is to generate a new <code>ImageData</code> and then paint it. In
   * this case, you'll set the location of your painting to
   * <code>top_left</code> and set <code>src_rect</code> to <code>NULL</code>.
   * The second is that you're generating small invalid regions out of a larger
   * bitmap representing your entire instance. In this case, you would set the
   * location of your image to (0,0) and then set <code>src_rect</code> to the
   * pixels you changed.
   *
   * @param[in] resource The 2D Graphics resource.
   * @param[in] image The <code>ImageData</code> to be painted.
   * @param[in] top_left A <code>Point</code> representing the
   * <code>top_left</code> location where the <code>ImageData</code> will be
   * painted.
   * @param[in] src_rect The rectangular area where the <code>ImageData</code>
   * will be painted.
   */
  void PaintImageData(
      [in] PP_Resource graphics_2d,
      [in] PP_Resource image_data,
      [in] PP_Point top_left,
      [in] PP_Rect src_rect);

  /**
   * Scroll() enqueues a scroll of the context's backing store. This
   * function has no effect until you call Flush(). The data within the
   * provided clipping rectangle will be shifted by (dx, dy) pixels.
   *
   * This function will result in some exposed region which will have undefined
   * contents. The module should call PaintImageData() on these exposed regions
   * to give the correct contents.
   *
   * The scroll can be larger than the area of the clipping rectangle, which
   * means the current image will be scrolled out of the rectangle. This
   * scenario is not an error but will result in a no-op.
   *
   * @param[in] graphics_2d The 2D Graphics resource.
   * @param[in] clip The clipping rectangle.
   * @param[in] amount The amount the area in the clipping rectangle will
   * shifted.
   */
  void Scroll(
      [in] PP_Resource graphics_2d,
      [in] PP_Rect clip_rect,
      [in] PP_Point amount);

  /**
   * ReplaceContents() provides a slightly more efficient way to paint the
   * entire module's image. Normally, calling PaintImageData() requires that
   * the browser copy the pixels out of the image and into the graphics
   * context's backing store. This function replaces the graphics context's
   * backing store with the given image, avoiding the copy.
   *
   * The new image must be the exact same size as this graphics context. If the
   * new image uses a different image format than the browser's native bitmap
   * format (use <code>PPB_ImageData.GetNativeImageDataFormat()</code> to
   * retrieve the format), then a conversion will be done inside the browser
   * which may slow the performance a little bit.
   *
   * <strong>Note:</strong> The new image will not be painted until you call
   * Flush().
   *
   * After this call, you should take care to release your references to the
   * image. If you paint to the image after ReplaceContents(), there is the
   * possibility of significant painting artifacts because the page might use
   * partially-rendered data when copying out of the backing store.
   *
   * In the case of an animation, you will want to allocate a new image for the
   * next frame. It is best if you wait until the flush callback has executed
   * before allocating this bitmap. This gives the browser the option of
   * caching the previous backing store and handing it back to you (assuming
   * the sizes match). In the optimal case, this means no bitmaps are allocated
   * during the animation, and the backing store and "front buffer" (which the
   * plugin is painting into) are just being swapped back and forth.
   *
   * @param[in] graphics_2d The 2D Graphics resource.
   * @param[in] image The <code>ImageData</code> to be painted.
   */
  void ReplaceContents(
      [in] PP_Resource graphics_2d,
      [in] PP_Resource image_data);

  /**
   * Flush() flushes any enqueued paint, scroll, and replace commands to the
   * backing store. This function actually executes the updates, and causes a
   * repaint of the webpage, assuming this graphics context is bound to a module
   * instance.
   *
   * Flush() runs in asynchronous mode. Specify a callback function and the
   * argument for that callback function. The callback function will be
   * executed on the calling thread when the image has been painted to the
   * screen. While you are waiting for a flush callback, additional calls to
   * Flush() will fail.
   *
   * Because the callback is executed (or thread unblocked) only when the
   * instance's image is actually on the screen, this function provides
   * a way to rate limit animations. By waiting until the image is on the
   * screen before painting the next frame, you can ensure you're not
   * flushing 2D graphics faster than the screen can be updated.
   *
   * <strong>Unbound contexts</strong>
   * If the context is not bound to a module instance, you will
   * still get a callback. The callback will execute after Flush() returns
   * to avoid reentrancy. The callback will not wait until anything is
   * painted to the screen because there will be nothing on the screen. The
   * timing of this callback is not guaranteed and may be deprioritized by
   * the browser because it is not affecting the user experience.
   *
   * <strong>Off-screen instances</strong>
   * If the context is bound to an instance that is currently not visible (for
   * example, scrolled out of view) it will behave like the "unbound context"
   * case.
   *
   * <strong>Detaching a context</strong>
   * If you detach a context from a module instance, any pending flush
   * callbacks will be converted into the "unbound context" case.
   *
   * <strong>Released contexts</strong>
   * A callback may or may not get called even if you have released all
   * of your references to the context. This scenario can occur if there are
   * internal references to the context suggesting it has not been internally
   * destroyed (for example, if it is still bound to an instance) or due to
   * other implementation details. As a result, you should be careful to
   * check that flush callbacks are for the context you expect and that
   * you're capable of handling callbacks for unreferenced contexts.
   *
   * <strong>Shutdown</strong>
   * If a module instance is removed when a flush is pending, the
   * callback will not be executed.
   *
   * @param[in] graphics_2d The 2D Graphics resource.
   * @param[in] callback A <code>CompletionCallback</code> to be called when
   * the image has been painted on the screen.
   *
   * @return Returns <code>PP_OK</code> on success or
   * <code>PP_ERROR_BADRESOURCE</code> if the graphics context is invalid,
   * <code>PP_ERROR_BADARGUMENT</code> if the callback is null and flush is
   * being called from the main thread of the module, or
   * <code>PP_ERROR_INPROGRESS</code> if a flush is already pending that has
   * not issued its callback yet.  In the failure case, nothing will be updated
   * and no callback will be scheduled.
   */
  int32_t Flush(
      [in] PP_Resource graphics_2d,
      [in] PP_CompletionCallback callback);

  /**
   * SetScale() sets the scale factor that will be applied when painting the
   * graphics context onto the output device. Typically, if rendering at device
   * resolution is desired, the context would be created with the width and
   * height scaled up by the view's GetDeviceScale and SetScale called with a
   * scale of 1.0 / GetDeviceScale(). For example, if the view resource passed
   * to DidChangeView has a rectangle of (w=200, h=100) and a device scale of
   * 2.0, one would call Create with a size of (w=400, h=200) and then call
   * SetScale with 0.5. One would then treat each pixel in the context as a
   * single device pixel.
   *
   * @param[in] resource A <code>Graphics2D</code> context resource.
   * @param[in] scale The scale to apply when painting.
   *
   * @return Returns <code>PP_TRUE</code> on success or <code>PP_FALSE</code> if
   * the resource is invalid or the scale factor is 0 or less.
   */
  [version=1.1]
  PP_Bool SetScale(
      [in] PP_Resource resource,
      [in] float_t scale);

  /***
   * GetScale() gets the scale factor that will be applied when painting the
   * graphics context onto the output device.
   *
   * @param[in] resource A <code>Graphics2D</code> context resource.
   *
   * @return Returns the scale factor for the graphics context. If the resource
   * is not a valid <code>Graphics2D</code> context, this will return 0.0.
   */
  [version=1.1]
  float_t GetScale(
      [in] PP_Resource resource);

  /**
   * SetLayerTransform() sets a transformation factor that will be applied for
   * the current graphics context displayed on the output device.  If both
   * SetScale and SetLayerTransform will be used, they are going to get combined
   * for the final result.
   *
   * This function has no effect until you call Flush().
   *
   * @param[in] scale The scale to be applied.
   * @param[in] origin The origin of the scale.
   * @param[in] translate The translation to be applied.
   *
   * @return Returns <code>PP_TRUE</code> on success or <code>PP_FALSE</code>
   * if the resource is invalid or the scale factor is 0 or less.
   */
  [version=1.2]
  PP_Bool SetLayerTransform(
      [in] PP_Resource resource,
      [in] float_t scale,
      [in] PP_Point origin,
      [in] PP_Point translate);
};

