/// <summary> /// Contains the rendering logic for this Layer2d. /// </summary> /// <remarks> /// The rendering logic in a Layer2d can be defined either by setting the <see cref="P:Renderer"/> property, /// or by overriding this method in a subclass. /// In either case, the rendering routine may be a fiber that continues rendering, possibly in an infinite loop (i.e for animation), /// or it can be a one-off draw something and return routine. If the first case is desired, it is recommended that /// it be implemented as an asynchronous method that is processed by the postcompiler. At the least, a Future that supports cancellation /// must be returned if the method does not complete synchronously. /// For an explanation, take an animation that continues in an indefinite loop, delaying for a certain period between iterations. /// If another layer is placed atop the animation layer, and then moved, exposing a previously unexposed region of the animation layer, /// that region needs to be drawn expeditiously. To accomplish that, the view system will cancel the animation's Future (as returned by /// a previous invocation of this method), and immediately invoke this method again. Thus, any state needed to correctly render the layer /// must not be stored in locals of an asynchronous method. /// </remarks> /// <param name='rect'> /// The BoundingRect into which rendering is required. /// </param> /// <param name='ctx'> /// The ISurface2d into which rendering is required. /// </param> protected virtual Future Render(BoundingRect rect, IContext2d ctx) { if (Renderer != null) return Renderer (this, rect, ctx); return Future.Fulfilled; }
public void ApplyTransform(IContext2d ctx) { if (Parent != null) Parent.ApplyTransform (ctx); if (transform) { // transform the context relative to this layer ctx.Translate (Bounds.X, Bounds.Y); // clip the context to this layers's dimensions ctx.BeginPath (); ctx.Rect (0, 0, Bounds.Width, Bounds.Height); ctx.Clip (); // if a scale factor is set, do that too ctx.Scale (ScaleX, ScaleY); } }