(*--------------------------------------------------------------------------- Copyright (c) 2025 Anil Madhavapeddy. All rights reserved. SPDX-License-Identifier: ISC ---------------------------------------------------------------------------*) (** Frame Composition Operations for compositing rectangular regions between animation frames. This allows building complex frames from simpler components. {2 Protocol Overview} Frame composition uses action [a=c] to copy a rectangular region from one frame onto another. This is useful for: - Building frames from reusable sprite components - Applying partial updates to existing frames - Creating complex animations efficiently {2 Coordinate System} All coordinates are in pixels, relative to the top-left corner of the respective frame: - [source_x], [source_y]: Top-left of rectangle in source frame - [dest_x], [dest_y]: Top-left of destination in target frame - [width], [height]: Size of the rectangle to copy If width/height are omitted, the entire source frame is used. {2 Composition Mode} The [composition] parameter controls blending: - [{`Alpha_blend}]: Standard alpha compositing (default) - [{`Overwrite}]: Direct pixel replacement {2 Error Conditions} The terminal responds with errors for: - [ENOENT]: Source or destination frame doesn't exist - [EINVAL]: Rectangle out of bounds, or source equals destination with overlapping regions - [ENOSPC]: Not enough storage after composition {2 Example} {[ (* Copy a 32x32 sprite from frame 2 to frame 5 *) let comp = Compose.make ~source_frame:2 ~dest_frame:5 ~width:32 ~height:32 ~source_x:0 ~source_y:0 (* From top-left of source *) ~dest_x:100 ~dest_y:50 () (* To position in dest *) in Kgp.compose ~image_id:1 comp ]} *) type t (** Composition operation. Opaque type; use {!make} to construct. *) val make : source_frame:int -> dest_frame:int -> ?width:int -> ?height:int -> ?source_x:int -> ?source_y:int -> ?dest_x:int -> ?dest_y:int -> ?composition:Kgp_composition.t -> unit -> t (** Create a composition operation. @param source_frame 1-based frame number to copy from. Required. Protocol key: [r]. @param dest_frame 1-based frame number to copy onto. Required. Protocol key: [c]. @param width Width of rectangle in pixels. Default is full frame. Protocol key: [w]. @param height Height of rectangle in pixels. Default is full frame. Protocol key: [h]. @param source_x Left edge of source rectangle (default 0). Protocol key: [X]. @param source_y Top edge of source rectangle (default 0). Protocol key: [Y]. @param dest_x Left edge of destination position (default 0). Protocol key: [x]. @param dest_y Top edge of destination position (default 0). Protocol key: [y]. @param composition Blending mode. Default is alpha blending. Protocol key: [C]. *) (** {1 Field Accessors} *) val source_frame : t -> int (** 1-based source frame number. *) val dest_frame : t -> int (** 1-based destination frame number. *) val width : t -> int option (** Width of rectangle in pixels. *) val height : t -> int option (** Height of rectangle in pixels. *) val source_x : t -> int option (** Left edge of source rectangle. *) val source_y : t -> int option (** Top edge of source rectangle. *) val dest_x : t -> int option (** Left edge of destination position. *) val dest_y : t -> int option (** Top edge of destination position. *) val composition : t -> Kgp_composition.t option (** Blending mode for composition. *)