JSDoc: Source: runner/bitmap.js

define([
  './asset_display_object',
  '../tools',
  '../point'
], function(AssetDisplayObject, tools, Point) {
  'use strict';
  var data = tools.descriptorData, accessor = tools.descriptorAccessor;
  var getSource = tools.getter('_source');
  function setSource(source) {
    this._source = source;
    this._owner.request(source);
  }
  /**
   * The Bitmap constructor
   *
   * @constructor
   * @name Bitmap
   * @extends AssetDisplayObject
   *
   * @param {AssetLoader} loader The asset loader to use;
   * @param {String} [source] The URL location of the movie to load.
   * @param {Function} [callback] A callback to be called when your movie has
   *  loaded (only called if you passed a `url`). The callback will be called
   *  with it's first argument signifying an error. So, if the first argument
   *  is `null` you can assume the movie was loaded successfully.
   *
   * @property {__list__} __supportedAttributes__ List of supported attribute names.
   *    In addition to the property names listed for DisplayObject,
   *    these are the attribute names you can pass to the attr() method. Note
   *    that this property is not available in your code, it's just here for
   *    documentation purposes.
   * @property {string} __supportedAttributes__.source The source of the bitmap.
   * @property {number} __supportedAttributes__.height The height of the bitmap.
   * @property {number} __supportedAttributes__.width The width of the bitmap.
   *
   */
  function Bitmap(loader, source, callback) {
    AssetDisplayObject.call(this, loader, source, callback);
    this.type = 'Bitmap';
    Object.defineProperties(this._attributes, {
      height: data(null, true, true),
      width: data(null, true, true),
      _naturalWidth: data(0, true, true),
      _naturalHeight: data(0, true, true),
      source: accessor(getSource, setSource, true),
      _source: data('', true, true),
      _absoluteUrl: data('', true, true)
    });
    var rendererAttributes = this._renderAttributes;
    rendererAttributes.height = 'height';
    rendererAttributes.width = 'width';
    rendererAttributes.naturalHeight = '_naturalHeight';
    rendererAttributes.naturalWidth = '_naturalWidth';
    rendererAttributes.absoluteUrl = '_absoluteUrl';
    this.attr('source', source);
  }
  var parentPrototype = AssetDisplayObject.prototype;
  var parentPrototypeRequest = parentPrototype.request;
  /** @lends Bitmap.prototype */
  var proto = Bitmap.prototype = Object.create(parentPrototype);
  /**
   * Clones the method
   *
   * @returns {Bitmap} Cloned instance
   */
  proto.clone = function() {
    return new Bitmap(this._loader, this.attr('source'));
  };
  /**
   * @see AssetDisplayObject.request
   * @method
   * @this {Bitmap}
   * @param {String|Array} aRequest The request needs to accomplish the requirements of AssetRequest
   * @returns {Bitmap|AssetRequest} The current Bitmap Istance or an AssetRequest instance
   * @name request
   */
  proto.request = function(aRequest) {
    if (typeof aRequest === 'undefined') {
      return this._request;
    }
    parentPrototypeRequest.call(this, aRequest);
    // Save full absolute URL to _absoluteSource so that it is
    // send to the renderer as `attributes.source`:
    this._attributes._absoluteUrl = this._request.resources[0].src;
    return this;
  };
  /**
   * Notify the bitmap that the corresponding data has been loaded. To be used
   * by the asset loader.
   *
   * @private
   * @param {string} type Either 'load' or 'error'
   * @param data
   * @returns {this} The current instance
   *
   */
  proto.notify = function(type, data) {
    switch (type) {
      case 'load':
        this._attributes._naturalWidth = data.width;
        this._attributes._naturalHeight = data.height;
        if (this._attributes.width == null || this._attributes.height == null) {
          // Only send naturalWidth/Height to renderer if width/height haven't
          // been manually set.
          this._mutatedAttributes.naturalWidth = true;
          this._mutatedAttributes.naturalHeight = true;
        }
        this._mutatedAttributes.absoluteUrl = true;
        // We trigger the event asynchronously so as to ensure that any events
        // bound after instantiation are still triggered:
        this.emitAsync('load', this);
        this.markUpdate();
        break;
      case 'error':
        // We trigger the event asynchronously so as to ensure that any events
        // bound after instantiation are still triggered:
        this.emitAsync('error', Error(data.error), this);
        break;
    }
    return this;
  };
  /**
   * Get computed dimensions of the bitmap
   *
   * @param {Matrix} [transform=null] A transform to apply to all points
   *    before computation.
   * @returns {Object} an object with all box properties
   */
  proto.getBoundingBox = function(transform) {
    var value,
        box = {top: 0, right: 0, bottom: 0, left: 0},
        naturalWidth = this._attributes._naturalWidth,
        naturalHeight = this._attributes._naturalHeight,
        attrWidth = this.attr('width'),
        attrHeight = this.attr('height'),
        naturalRatio = naturalWidth / naturalHeight,
        // If one dimensions is not specified, then we use the other dimension
        // and the ratio to calculate its box:
        width = attrWidth || (
          attrHeight != null ? naturalRatio * attrHeight : naturalWidth
        ) || 0,
        height = attrHeight || (
          attrWidth != null ? attrWidth / naturalRatio : naturalHeight
        ) || 0,
        topLeft,
        bottomRight,
        dimensions;
    box.right = box.width = width;
    box.bottom = box.height = height;
    if (transform) {
      topLeft = transform.transformPoint(new Point(0, 0));
      bottomRight = transform.transformPoint(new Point(width, height));
      box.top = topLeft.y;
      box.left = topLeft.x;
      box.right = bottomRight.x;
      box.bottom = bottomRight.y;
    }
    return box;
  };
  return Bitmap;
});