Pārlūkot izejas kodu

API documentation: h2d package (#842)

Pavel Alexandrov 4 gadi atpakaļ
vecāks
revīzija
e4b94eeb84
70 mainītis faili ar 4545 papildinājumiem un 470 dzēšanām
  1. 37 14
      h2d/Anim.hx
  2. 16 5
      h2d/Bitmap.hx
  3. 44 1
      h2d/BlendMode.hx
  4. 127 35
      h2d/Camera.hx
  5. 28 1
      h2d/CdbLevel.hx
  6. 26 1
      h2d/CheckBox.hx
  7. 114 3
      h2d/Console.hx
  8. 26 11
      h2d/Drawable.hx
  9. 69 3
      h2d/Dropdown.hx
  10. 271 37
      h2d/Flow.hx
  11. 139 6
      h2d/Font.hx
  12. 151 0
      h2d/Graphics.hx
  13. 39 10
      h2d/HtmlText.hx
  14. 140 27
      h2d/Interactive.hx
  15. 47 2
      h2d/KeyFrames.hx
  16. 42 21
      h2d/Layers.hx
  17. 31 6
      h2d/Mask.hx
  18. 173 48
      h2d/Object.hx
  19. 30 1
      h2d/ObjectFollower.hx
  20. 226 12
      h2d/Particles.hx
  21. 159 7
      h2d/RenderContext.hx
  22. 30 2
      h2d/ScaleGrid.hx
  23. 121 53
      h2d/Scene.hx
  24. 35 0
      h2d/Slider.hx
  25. 1 0
      h2d/Sprite.hx
  26. 155 18
      h2d/SpriteBatch.hx
  27. 111 7
      h2d/Text.hx
  28. 83 1
      h2d/TextInput.hx
  29. 169 4
      h2d/Tile.hx
  30. 190 5
      h2d/TileGroup.hx
  31. 47 0
      h2d/Video.hx
  32. 20 3
      h2d/ZGroup.hx
  33. 139 17
      h2d/col/Bounds.hx
  34. 45 5
      h2d/col/Circle.hx
  35. 6 0
      h2d/col/Collider.hx
  36. 0 0
      h2d/col/Delaunay.hx
  37. 120 11
      h2d/col/IBounds.hx
  38. 68 7
      h2d/col/IPoint.hx
  39. 69 4
      h2d/col/IPolygon.hx
  40. 51 1
      h2d/col/IPolygons.hx
  41. 39 1
      h2d/col/Line.hx
  42. 119 2
      h2d/col/Matrix.hx
  43. 35 9
      h2d/col/PixelsCollider.hx
  44. 92 7
      h2d/col/Point.hx
  45. 65 4
      h2d/col/Polygon.hx
  46. 13 1
      h2d/col/PolygonCollider.hx
  47. 35 1
      h2d/col/Polygons.hx
  48. 3 0
      h2d/col/Polynomial.hx
  49. 29 1
      h2d/col/Ray.hx
  50. 34 1
      h2d/col/RoundRect.hx
  51. 58 1
      h2d/col/Segment.hx
  52. 33 3
      h2d/col/Segments.hx
  53. 35 2
      h2d/col/Triangle.hx
  54. 142 36
      h2d/col/Voronoi.hx
  55. 20 0
      h2d/filter/AbstractMask.hx
  56. 23 0
      h2d/filter/Ambient.hx
  57. 18 1
      h2d/filter/Bloom.hx
  58. 15 5
      h2d/filter/Blur.hx
  59. 33 1
      h2d/filter/ColorMatrix.hx
  60. 26 1
      h2d/filter/Displacement.hx
  61. 20 0
      h2d/filter/DropShadow.hx
  62. 51 1
      h2d/filter/Filter.hx
  63. 24 0
      h2d/filter/Glow.hx
  64. 24 0
      h2d/filter/Group.hx
  65. 13 0
      h2d/filter/Mask.hx
  66. 6 0
      h2d/filter/Nothing.hx
  67. 30 0
      h2d/filter/Outline.hx
  68. 44 0
      h2d/filter/Shader.hx
  69. 69 1
      h2d/impl/PointApi.hx
  70. 2 2
      hxd/Key.hx

+ 37 - 14
h2d/Anim.hx

@@ -1,38 +1,52 @@
 package h2d;
 
 /**
-	h2d.Anim is used to display an animated sequence of bitmap tiles on the screen.
+	Displays an animated sequence of bitmap Tiles on the screen.
+	
+	Anim does not provide animation sequence management and it's up to user on how to implement it.
+	Another limitation is framerate. Anim runs at a fixed framerate dictated by `Anim.speed`.
+	Switching animations can be done through `Anim.play` method.
+
+	Note that animation playback happens regardless of Anim visibility and only can be paused by `Anim.pause` flag. 
+	Anim should be added to an active `h2d.Scene` in order to function.
 **/
 class Anim extends Drawable {
 
 	/**
 		The current animation, as a list of tile frames to display.
-		If the frames are empty or if a tile is frames is null, a pink 5x5 bitmap will be displayed instead. Use remove() or visible=false to hide a h2d.Anim
+		If the frames are empty or if a tile is frames is null, a pink 5x5 bitmap will be displayed instead.
 	**/
 	public var frames(default,null) : Array<Tile>;
 
 	/**
-		The current frame the animation is currently playing. Always in `[0,frames.length]` range
+		The current frame the animation is currently playing. Always in `[0,frames.length]` range.
+		Use `Std.int(anim.currentFrame)` in order to obtain current frame index.
+		Fractional value represents the progress of current frame and increases according to `Anim.speed` value.
+
+		Setting frame to a negative value will wrap it around from the end of the animation. Setting negative value smaller than `-frames.length` lead to undefined behavior.
+		Setting frame to a value greater than `frames.length` would cause to wrap around.
 	**/
 	public var currentFrame(get,set) : Float;
 
 	/**
-		The speed (in frames per second) at which the animation is playing (default 15.)
+		The speed (in frames per second) at which the animation is playing.
+
+		Settings speed to a negative value is not supported and leads to undefined behavior.
 	**/
 	public var speed : Float;
 
 	/**
-		Setting pause will pause the animation, preventing any automatic change to currentFrame.
+		Setting pause will suspend the animation, preventing automatic accumulation of `Anim.currentFrame` over time.
 	**/
 	public var pause : Bool = false;
 
 	/**
-		Disabling loop will stop the animation at the last frame (default : true)
+		Disabling loop will stop the animation at the last frame.
 	**/
 	public var loop : Bool = true;
 
 	/**
-		When enable, fading will draw two consecutive frames with alpha transition between
+		When enabled, fading will draw two consecutive frames with alpha transition between
 		them instead of directly switching from one to another when it reaches the next frame.
 		This can be used to have smoother animation on some effects.
 	**/
@@ -41,13 +55,16 @@ class Anim extends Drawable {
 	var curFrame : Float;
 
 	/**
-		Create a new animation with the specified frames, speed and parent object
+		Create a new animation with the specified frames, speed and parent object.
+		@param frames An optional array of Tiles as an initial `Anim.frames` value.
+		@param speed The Anim playback speed in frames per second.
+		@param parent An optional parent `h2d.Object` instance to which Anim adds itself if set.
 	**/
-	public function new( ?frames : Array<Tile>, ?speed : Float, ?parent : h2d.Object ) {
+	public function new( ?frames : Array<Tile>, speed : Float = 15, ?parent : h2d.Object ) {
 		super(parent);
 		this.frames = frames == null ? [] : frames;
 		this.curFrame = 0;
-		this.speed = speed == null ? 15 : speed;
+		this.speed = speed;
 	}
 
 	inline function get_currentFrame() {
@@ -56,6 +73,8 @@ class Anim extends Drawable {
 
 	/**
 		Change the currently playing animation and unset the pause if it was set.
+		@param frames The list of frames to play.
+		@param atFrame Optional starting frame of the new animation.
 	**/
 	public function play( frames : Array<Tile>, atFrame = 0. ) {
 		this.frames = frames == null ? [] : frames;
@@ -64,9 +83,13 @@ class Anim extends Drawable {
 	}
 
 	/**
-		onAnimEnd is automatically called each time the animation will reach past the last frame.
-		If loop is true, it is called everytime the animation loops.
-		If loop is false, it is called once when the animation reachs `currentFrame == frames.length`
+		Sent each time the animation reaches past the last frame.
+
+		If `loop` is enabled, callback is sent every time the animation loops.
+		During the call, `currentFrame` is already wrapped around and represent new frame position so it's safe to modify it.
+
+		If `loop` is disabled, callback is sent only once when the animation reaches `currentFrame == frames.length`.
+		During the call, `currentFrame` is always equals to `frames.length`.
 	**/
 	public dynamic function onAnimEnd() {
 	}
@@ -103,7 +126,7 @@ class Anim extends Drawable {
 	}
 
 	/**
-		Return the tile at current frame.
+		Returns the Tile at current frame.
 	**/
 	public function getFrame() : Tile {
 		var i = Std.int(curFrame);

+ 16 - 5
h2d/Bitmap.hx

@@ -1,28 +1,39 @@
 package h2d;
 
 /**
-	h2d.Bitmap is used to display a single bitmap Tile on the screen.
+	Displays a single bitmap Tile on the screen.
+
+	It is a most primitive Drawable and easiest to use, but vastly inferior to others in terms of performance when used for rendering of many tiles.
+	When dealing with many images at once, it is recommended to use batched renderers, like `h2d.SpriteBatch` or `h2d.TileGroup`.
 **/
 class Bitmap extends Drawable {
 
 	/**
-		The tile to display see `h2d.Tile` documentation for details.
-		If the tile is null, a pink 5x5 bitmap will be displayed instead. Use remove() or visible=false to hide a h2d.Bitmap
+		The tile to display. See `h2d.Tile` documentation for details.
+		If the tile is null, a pink 5x5 bitmap will be displayed instead.
 	**/
 	public var tile(default,set) : Tile;
 
 	/**
-	 * 	If set, rescale the tile to match the given width, keeping the aspect ratio unless height is also set.
+		If set, rescale the tile to match the given width, keeping the aspect ratio unless `height` is also set.
+		
+		Note that both `width` and `height` are `null` by default and in order to retrieve bitmap dimensions with
+		scaling accurately, call `getSize` method or address `tile.width/height` to get unscaled dimensions.
 	**/
 	public var width(default,set) : Null<Float>;
 
 	/**
-	 * 	If set, rescale the tile to match the given height, keeping the aspect ratio unless width is also set.
+		If set, rescale the tile to match the given height, keeping the aspect ratio unless `width` is also set.
+
+		Note that both `width` and `height` are `null` by default and in order to retrieve bitmap dimensions with
+		scaling accurately, call `getSize` method or address `tile.width/height` to get unscaled dimensions.
 	**/
 	public var height(default,set) : Null<Float>;
 
 	/**
 		Create a Bitmap with specified tile and parent object.
+		@param tile A Tile that should be rendered by this Bitmap.
+		@param parent An optional parent `h2d.Object` instance to which Bitmap adds itself if set.
 	**/
 	public function new( ?tile : Tile, ?parent : h2d.Object ) {
 		super(parent);

+ 44 - 1
h2d/BlendMode.hx

@@ -1,16 +1,59 @@
 package h2d;
 
+/**
+	The blending rules when rendering a Tile/Material.
+**/
 enum BlendMode {
+	/**
+		`Out = 1 * Src + 0 * Dst`
+	**/
 	None;
+	/**
+		`Out = SrcA * Src + (1 - SrcA) * Dst`
+	**/
 	Alpha;
+	/**
+		`Out = SrcA * Src + 1 * Dst`
+	**/
 	Add;
+	/**
+		`Out = Src + (1 - SrcA) * Dst`
+	**/
 	AlphaAdd;
+	/**
+		`Out = (1 - Dst) * Src + 1 * Dst`
+	**/
 	SoftAdd;
+	/**
+		`Out = Dst * Src + 0 * Dst`
+	**/
 	Multiply;
+	/**
+		`Out = Dst * Src + (1 - SrcA) * Dst`
+	**/
 	AlphaMultiply;
+	/**
+		`Out = 0 * Src + (1 - Srb) * Dst`
+	**/
 	Erase;
+	/**
+		`Out = 1 * Src + (1 - Srb) * Dst`
+	**/
 	Screen;
+	/**
+		`Out = 1 * Dst - SrcA * Src`
+	**/
 	Sub;
+	/**
+		The output color is the max of the source and dest colors.  
+		The blend parameters Src and Dst are ignored for this equation.  
+		`Out = MAX( Src, Dst )`
+	**/
 	Max;
+	/**
+		The output color is the min of the source and dest colors.  
+		The blend parameters Src and Dst are ignored for this equation.  
+		`Out = MAX( Src, Dst )`
+	**/
 	Min;
-}
+}

+ 127 - 35
h2d/Camera.hx

@@ -1,12 +1,16 @@
 package h2d;
 
 /**
-	2D camera instance. Allows for positioning, scaling and rotation of 2D objects on the scene.
-	Per-layer visibility can be configured by overriding `layerVisible` method.
-	Camera can clip out contents outside of it's viewport by setting `clipViewport` to `true`.
-	Due to Heaps event handling structure, only one camera can handle scene events, and can be set with `h2d.Scene.interactiveCamera`.
-	When handling events, assigned camera isn't checked for it's nor layers visibiilty.
-	Camera system is circumvented if Scene would get any filter assigned to it.
+	A 2D camera representation attached to `h2d.Scene`.
+
+	Enables ability to move, scale and rotate the scene viewport.
+	
+	Scene supports usage of multiple Camera instances.
+	To configure which layers each Camera renders - `Camera.layerVisible` method should be overridden.
+	By default, camera does not clip out the contents that are outside camera bounding box, which can be enabled through `Camera.clipViewport`.
+	
+	Due to Heaps event handling structure, only one Camera instance can handle the mouse/touch input, and can be set through `h2d.Scene.interactiveCamera` variable.
+	Note that during even handing, interactive camera does not check if the Camera itself is visible nor the layers filters as well as `clipViewport` is not applied.
 **/
 @:access(h2d.RenderContext)
 @:access(h2d.Scene)
@@ -37,16 +41,18 @@ class Camera {
 	public var rotation(default, set) : Float;
 
 	/**
-		Enables viewport clipping. Allow to restrict rendering area of the camera.
+		Enables viewport clipping. Allow to restrict rendering area of the camera to the viewport boundaries.
+
+		Does not affect the user input when Camera is set as interactive camera.
 	**/
 	public var clipViewport : Bool;
 	/**
-		Horizontal viewport offset of the camera relative to internal scene viewport (see h2d.Scene.scaleMode) in scene coordinates. ( default : 0 )  
+		Horizontal viewport offset of the camera relative to internal scene viewport (see `h2d.Scene.scaleMode`) in scene coordinates. ( default : 0 )  
 		Automatically scales on scene resize.
 	**/
 	public var viewportX(get, set) : Float;
 	/**
-		Vertical viewport offset of the camera relative to internal scene viewport (see h2d.Scene.scaleMode) in scene coordinates. ( default : 0 )  
+		Vertical viewport offset of the camera relative to internal scene viewport (see `h2d.Scene.scaleMode`) in scene coordinates. ( default : 0 )  
 		Automatically scales on scene resize.
 	**/
 	public var viewportY(get, set) : Float;
@@ -68,17 +74,25 @@ class Camera {
 	public var anchorX(default, set) : Float;
 	/**
 		Vertical anchor position inside viewport boundaries used for positioning and resize compensation. ( default : 0 )  
-		Value is apercentile (0..1) from top viewport edge to bottom viewport edge with 0.5 being center.
+		Value is a percentile (0..1) from top viewport edge to bottom viewport edge with 0.5 being center.
 	**/
 	public var anchorY(default, set) : Float;
 
-	/** Camera visibility. Does not affect event handling for interactive camera. **/
+	/**
+		Camera visibility.
+		
+		Does not affect the user input when Camera is set as interactive camera.
+	**/
 	public var visible : Bool;
 
-	/** Set to enable primitive position sync between camera and target Object. **/
+	/**
+		Makes camera to follow the referenced Object position.
+	**/
 	public var follow : h2d.Object;
-	/** Syncs camera rotation to follow object rotation. **/
-	public var followRotation : Bool;
+	/**
+		Enables `h2d.Object.rotation` sync between `Camera.follow` object and Camera.
+	**/
+	public var followRotation : Bool = false;
 
 	var posChanged : Bool;
 
@@ -97,6 +111,11 @@ class Camera {
 
 	var scene : Scene;
 
+	/**
+		Create a new Camera instance and attach to the given `scene`.
+		@param scene Optional owner Scene to which camera auto-attaches to.
+		Note that when Camera is not attached to the Scene, a number of methods would lead to an error if called.
+	**/
 	public function new( ?scene : Scene ) {
 		this.x = 0; this.y = 0;
 		this.scaleX = 1; this.scaleY = 1;
@@ -109,19 +128,49 @@ class Camera {
 		if (scene != null) scene.addCamera(this);
 	}
 
+	/**
+		Detaches Camera from the Scene it currently attached to.
+	**/
 	public inline function remove() {
 		if (scene != null) scene.removeCamera(this);
 	}
 
 	/**
 		Override this method to set visibility only to specific layers. Renders all layers by default.
-		Layer visibility is not checked during Interactive event handling.
+
+		Does not affect the user input when Camera is set as interactive camera.
+
+		Usage example:
+		
+		```haxe
+		final LAYER_SHARED = 0;
+		final LAYER_PLAYER_1 = 2;
+		final LAYER_PLAYER_2 = 3;
+		final LAYER_UI = 4;
+		// Set first camera to only render shared layer and one that only visible to player 1.
+		s2d.camera.layerVisible = (layer) -> layer == LAYER_SHARED || layer == LAYER_PLAYER_1;
+		var player2 = new h2d.Camera(s2d);
+		// Set second camera to only render shared layer and one that only visible to player 2.
+		player2.layerVisible = (layer) -> layer == LAYER_SHARED || layer == LAYER_PLAYER_2;
+		var ui = new h2d.Camera(s2d);
+		// Set last camera to only render UI layer.
+		ui.layerVisible = (layer) -> layer == LAYER_UI;
+		```
+
+		@param layer The rendered layer index in `h2d.Scene`.
+		@returns `true` if layer can be rendered, `false` otherwise.
+
 	**/
 	public dynamic function layerVisible( layer : Int ) : Bool {
 		return true;
 	}
+	
+	/**
+		<span class="label">Internal usage</span>
 
-	@:noCompletion public function enter( ctx : RenderContext ) {
+		Prepares RenderContext to render the camera contents and clips viewport if necessary. Should call `Camera.exit` afterwards.
+	**/
+	@:dox(hide) @:noCompletion public function enter( ctx : RenderContext ) {
 		ctx.pushCamera(this);
 		if ( clipViewport ) {
 			var old = ctx.inFilter;
@@ -131,7 +180,12 @@ class Camera {
 		}
 	}
 
-	@:noCompletion public function exit( ctx : RenderContext ) {
+	/**
+		<span class="label">Internal usage</span>
+
+		Causes RenderContext to restore the state prior to camera rendering. Should be called after `Camera.enter` when rendering is finished.
+	**/
+	@:dox(hide) @:noCompletion public function exit( ctx : RenderContext ) {
 		if ( clipViewport ) {
 			var old = ctx.inFilter;
 			ctx.inFilter = null;
@@ -141,7 +195,12 @@ class Camera {
 		ctx.popCamera();
 	}
 
-	@:access(h2d.Object)
+	/**
+		<span class="label">Internal usage</span>
+
+		Synchronizes the camera transform matrix.
+	**/
+	@:access(h2d.Object) @:dox(hide) @:noCompletion
 	public function sync( ctx : RenderContext, force : Bool = false )
 	{
 		if (scene == null) return;
@@ -172,30 +231,48 @@ class Camera {
 		}
 	}
 
+	/**
+		Sets the `Camera.scaleX` and `Camera.scaleY` to given `x` and `y`.
+	**/
 	public inline function setScale( x : Float, y : Float ) {
 		this.scaleX = x;
 		this.scaleY = y;
 	}
 
+	/**
+		Multiplies the `Camera.scaleX` by `x` and `Camera.scaleY` by `y`.
+	**/
 	public inline function scale( x : Float, y : Float ) {
 		this.scaleX *= x;
 		this.scaleY *= y;
 	}
 
+	/**
+		Sets the camera position to given `x` and `y`.
+	**/
 	public inline function setPosition( x : Float, y : Float ) {
 		this.x = x;
 		this.y = y;
 	}
 
+	/**
+		Moves the camera position by given `dx` and `dy`.
+	**/
 	public inline function move( dx : Float, dy : Float ) {
 		this.x += dx;
 		this.y += dy;
 	}
 
-	public inline function rotate( v : Float ) {
-		this.rotation += v;
+	/**
+		Rotates the camera relative to current rotation by given `angle` in radians.
+	**/
+	public inline function rotate( angle : Float ) {
+		this.rotation += angle;
 	}
 
+	/**
+		Sets the `Camera.anchorX` and `Camera.anchorY` to given `x` and `y`.
+	**/
 	public inline function setAnchor( x : Float, y : Float ) {
 		this.anchorX = x;
 		this.anchorY = y;
@@ -203,6 +280,8 @@ class Camera {
 
 	/**
 		Sets camera viewport dimensions. If `w` or `h` arguments are 0 - scene size is used (width or height respectively).
+
+		Requires Camera being attached to a Scene.
 	**/
 	public inline function setViewport( x : Float = 0, y : Float = 0, w : Float = 0, h : Float = 0 ) {
 		checkScene();
@@ -223,10 +302,11 @@ class Camera {
 		posChanged = true;
 	}
 
-	// Scren <-> Camera
+	// Screen <-> Camera
 	/**
 		Convert screen position into a local camera position.
-		Requires Scene as a reference to viewport of `scaleMode`.
+		
+		Requires Camera being attached to a Scene.
 	**/
 	inline function screenXToCamera( mx : Float, my : Float ) : Float {
 		return sceneXToCamera((mx - scene.offsetX) / scene.viewportScaleX, (my - scene.offsetY) / scene.viewportScaleY);
@@ -234,7 +314,8 @@ class Camera {
 
 	/**
 		Convert screen position into a local camera position.
-		Requires Scene as a reference to viewport of `scaleMode`.
+		
+		Requires Camera being attached to a Scene.
 	**/
 	inline function screenYToCamera( mx : Float, my : Float ) : Float {
 		return sceneYToCamera((mx - scene.offsetX) / scene.viewportScaleX, (my - scene.offsetY) / scene.viewportScaleY);
@@ -242,7 +323,8 @@ class Camera {
 
 	/**
 		Convert local camera position to absolute screen position.
-		Requires Scene as a reference to viewport of `scaleMode`.
+		
+		Requires Camera being attached to a Scene.
 	**/
 	inline function cameraXToScreen( mx : Float, my : Float ) : Float {
 		return cameraXToScene(mx, my) * scene.viewportScaleX + scene.offsetX;
@@ -250,7 +332,8 @@ class Camera {
 
 	/**
 		Convert local camera position to absolute screen position.
-		Requires Scene as a reference to viewport of `scaleMode`.
+		
+		Requires Camera being attached to a Scene.
 	**/
 	inline function cameraYToScreen( mx : Float, my : Float ) : Float {
 		return cameraYToScene(mx, my) * scene.viewportScaleY + scene.offsetY;
@@ -259,7 +342,7 @@ class Camera {
 	// Scene <-> Camera
 	/**
 		Convert an absolute scene position into a local camera position.
-		Does not represent screen position, see `screenXToCamera` to convert position with accounting of `scaleMode`.
+		Does not represent screen position, see `Camera.screenXToCamera` to convert position with accounting of `scaleMode`.
 	**/
 	inline function sceneXToCamera( mx : Float, my : Float ) : Float {
 		return ((mx - absX) * matD - (my - absY) * matC) * invDet;
@@ -267,7 +350,7 @@ class Camera {
 
 	/**
 		Convert an absolute scene position into a local camera position.
-		Does not represent screen position, see `screenYToCamera` to convert position with accounting of `scaleMode`.
+		Does not represent screen position, see `Camera.screenYToCamera` to convert position with accounting of `scaleMode`.
 	**/
 	inline function sceneYToCamera( mx : Float, my : Float ) : Float {
 		return (-(mx - absX) * matB + (my - absY) * matA) * invDet;
@@ -275,7 +358,7 @@ class Camera {
 
 	/**
 		Convert local camera position into absolute scene position.
-		Does not represent screen position, see `cameraXToScreen` to convert position with accounting of `scaleMode`.
+		Does not represent screen position, see `Camera.cameraXToScreen` to convert position with accounting of `scaleMode`.
 	**/
 	inline function cameraXToScene( mx : Float, my : Float ) : Float {
 		return mx * matA + my * matC + absX;
@@ -283,15 +366,18 @@ class Camera {
 
 	/**
 		Convert local camera position into absolute scene position.
-		Does not represent screen position, see `cameraYToScreen` to convert position with accounting of `scaleMode`.
+		Does not represent screen position, see `Camera.cameraYToScreen` to convert position with accounting of `scaleMode`.
 	**/
 	inline function cameraYToScene( mx : Float, my : Float ) : Float {
 		return mx * matB + my * matD + absY;
 	}
 
 	// Point/event
-
-	@:noCompletion public function eventToCamera( e : hxd.Event ) {
+	/**
+		<span class="label">Internal usage</span>
+		Convert `Event.relX` and `Event.relY` to local camera position.
+	**/
+	@:dox(hide) @:noCompletion public function eventToCamera( e : hxd.Event ) {
 		var x = (e.relX - scene.offsetX) / scene.viewportScaleX - absX;
 		var y = (e.relY - scene.offsetY) / scene.viewportScaleY - absY;
 		e.relX = (x * matD - y * matC) * invDet;
@@ -300,7 +386,8 @@ class Camera {
 
 	/**
 		Convert screen position into a local camera position.
-		Requires Scene as a reference to viewport of `scaleMode`.
+
+		Requires Camera being attached to a Scene.
 	**/
 	public function screenToCamera( pt : h2d.col.Point ) {
 		checkScene();
@@ -312,7 +399,8 @@ class Camera {
 
 	/**
 		Convert local camera position to absolute screen position.
-		Requires Scene as a reference to viewport of `scaleMode`.
+
+		Requires Camera being attached to a Scene.
 	**/
 	public function cameraToScreen( pt : h2d.col.Point ) {
 		checkScene();
@@ -324,7 +412,9 @@ class Camera {
 
 	/**
 		Convert an absolute scene position into a local camera position.
-		Does not represent screen position, see `screenToCamera` to convert position with accounting of `scaleMode`.
+		Does not represent screen position, see `Camera.screenToCamera` to convert position with accounting of `scaleMode`.
+
+		Requires Camera being attached to a Scene.
 	**/
 	public function sceneToCamera( pt : h2d.col.Point ) {
 		checkScene();
@@ -336,7 +426,9 @@ class Camera {
 
 	/**
 		Convert local camera position into absolute scene position.
-		Does not represent screen position, see `cameraToScreen` to convert position with accounting of `scaleMode`.
+		Does not represent screen position, see `Camera.cameraToScreen` to convert position with accounting of `scaleMode`.
+		
+		Requires Camera being attached to a Scene.
 	**/
 	public function cameraToScene( pt : h2d.col.Point ) {
 		checkScene();

+ 28 - 1
h2d/CdbLevel.hx

@@ -4,17 +4,26 @@ package h2d;
 "Please compile with -lib castle"
 #end
 
+/**
+	[CastleDB](http://castledb.org) integration; A part of `CdbLevel` decoder.
+**/
 typedef TileSpec = {
 	var file(default, never) : String;
 	var stride(default, never) : Int;
 	var size(default, never) : Int;
 }
 
+/**
+	[CastleDB](http://castledb.org) integration; A part of `CdbLevel` decoder.
+**/
 typedef LayerSpec = {
 	var name : String;
 	var data : cdb.Types.TileLayer;
 }
 
+/**
+	[CastleDB](http://castledb.org) integration; A part of `CdbLevel` decoder.
+**/
 typedef LevelSpec = {
 	var width : Int;
 	var height : Int;
@@ -23,6 +32,9 @@ typedef LevelSpec = {
 	var layers : Array<LayerSpec>;
 }
 
+/**
+	[CastleDB](http://castledb.org) integration; A part of `CdbLevel` decoder.
+**/
 class LevelTileset {
 	public var stride : Int;
 	public var size : Int;
@@ -45,6 +57,9 @@ class LevelTileset {
 	}
 }
 
+/**
+	[CastleDB](http://castledb.org) integration; A part of `CdbLevel` decoder.
+**/
 class LevelObject {
 	public var tileset : LevelTileset;
 	public var id : Int;
@@ -67,6 +82,9 @@ class LevelObject {
 	}
 }
 
+/**
+	[CastleDB](http://castledb.org) integration; A part of `CdbLevel` decoder.
+**/
 class LevelGroup {
 	public var tileset : LevelTileset;
 	public var name : String;
@@ -92,6 +110,9 @@ class LevelGroup {
 	}
 }
 
+/**
+	[CastleDB](http://castledb.org) integration; A part of `CdbLevel` decoder.
+**/
 class LevelObjectInstance {
 	public var x : Int;
 	public var y : Int;
@@ -102,12 +123,18 @@ class LevelObjectInstance {
 	}
 }
 
+/**
+	[CastleDB](http://castledb.org) integration; A part of `CdbLevel` decoder.
+**/
 enum LevelLayerData {
 	LTiles( data : Array<Int> );
 	LGround( data : Array<Int> );
 	LObjects( objects : Array<LevelObjectInstance> );
 }
 
+/**
+	[CastleDB](http://castledb.org) integration; A part of `CdbLevel` decoder.
+**/
 class LevelLayer {
 
 	/**
@@ -243,7 +270,7 @@ class LevelLayer {
 }
 
 /**
-	CdbLevel will decode and display a level created with the CastleDB level editor.
+	A decoder and renderer for levels created with the CastleDB 2D level editor.
 	See http://castledb.org for more details.
 **/
 class CdbLevel extends Layers {

+ 26 - 1
h2d/CheckBox.hx

@@ -1,14 +1,35 @@
 package h2d;
 
+/**
+	A simple Interactive checkbox button with a label.
+
+	Useful for fast construction of development UI, but lacks on configurability side.
+**/
 class CheckBox extends h2d.Flow {
+	/**
+		When disabled, the user would not be able to change the checkbox state by interacting with it.
 
+		It is still possible to change the `selected` state manually through the code even if checkbox is disabled.
+	**/
 	public var enable(default,set) : Bool = true;
+	/**
+		Current toggle state of the checkbox.
+
+		Note that changing the state from the code will cause `CheckBox.onChange` to trigger.
+	**/
 	public var selected(default,set) : Bool = false;
+	/**
+		Optional text label that will be shown to the right of the checkbox.
+	**/
 	public var text(default,set) : String = "";
 
 	var tf : h2d.Text;
 	var select : h2d.Bitmap;
 
+	/**
+		Create a new CheckBox instance.
+		@param parent An optional parent `h2d.Object` instance to which CheckBox adds itself if set.
+	**/
 	public function new(?parent) {
 		super(parent);
 		padding = 0;
@@ -69,6 +90,10 @@ class CheckBox extends h2d.Flow {
 		return selected;
 	}
 
+	/**
+		Sent when the `CheckBox.selected` state is changed.
+		Can be triggered both by user interaction (when checkbox is enabled) and from the software side by changing `selected` directly.
+	**/
 	public dynamic function onChange() {
 	}
-}
+}

+ 114 - 3
h2d/Console.hx

@@ -2,23 +2,70 @@ package h2d;
 
 import hxd.Key;
 
+/**
+	The console argument type.
+**/
 enum ConsoleArg {
+	/**
+		An integer parameter.
+	**/
 	AInt;
+	/**
+		A floating-point parameter.
+	**/
 	AFloat;
+	/**
+		A text string parameter.
+	**/
 	AString;
+	/**
+		A boolean parameter. Can be `true`, `false`, `1` or `0`.
+	**/
 	ABool;
+	/**
+		A text string parameter with limitation to only accept the specified list values.
+	**/
 	AEnum( values : Array<String> );
 }
 
+/**
+	A descriptor for an argument of a console command.
+**/
 typedef ConsoleArgDesc = {
+	/**
+		A human-readable argument name.
+	**/
 	name : String,
+	/**
+		The type of the argument.
+	**/
 	t : ConsoleArg,
+	/**
+		When set, argument is considered optional and command callback will receive `null` if argument was omitted.
+		Inserting optional arguments between non-optional arguments leads to an undefined behavior.
+	**/
 	?opt : Bool,
 }
 
+/**
+	A simple debug console integration.
+
+	Console can be focused manually through `Console.show` and `Console.hide` methods
+	as well as by pressing the key defined by `Console.shortKeyChar`.
+
+	It's possible to log messages to console via `Console.log` method.
+
+	By default comes with 2 commands: `help` and `cls`, which print help message
+	describing all commands and clears the console logs respectively.
+
+	To add custom commands, use `Console.add` and `Console.addCommand` methods.
+**/
 class Console #if !macro extends h2d.Object #end {
 
 	#if !macro
+	/**
+		The timeout in seconds before log will automatically hide after the last message.
+	**/
 	public static var HIDE_LOG_TIMEOUT = 3.;
 
 	var width : Int;
@@ -35,9 +82,20 @@ class Console #if !macro extends h2d.Object #end {
 	var logIndex:Int;
 	var curCmd:String;
 
+	/**
+		The text character which should be pressed in order to automatically show console input.
+	**/
 	public var shortKeyChar : Int = "/".code;
+	/**
+		Provide an auto-complete on Enter/Tab key and command completion hints.
+	**/
 	public var autoComplete : Bool = true;
 
+	/**
+		Create a new Console instance using the provided font and parent.
+		@param font The font to use for console text input and log.
+		@param parent An optional parent `h2d.Object` instance to which Console adds itself if set.
+	**/
 	public function new(font:h2d.Font,?parent) {
 		super(parent);
 		height = Math.ceil(font.lineHeight) + 2;
@@ -74,12 +132,43 @@ class Console #if !macro extends h2d.Object #end {
 		addAlias("?", "help");
 	}
 
-	public function addCommand( name, ?help, args, callb : Dynamic ) {
+	/**
+		Add a new command to console.
+		@param name Command name.
+		@param help Optional command description text.
+		@param args An array of command arguments. 
+		@param callb The callback method taking the arguments listed in `args`.
+	**/
+	public function addCommand( name, ?help, args : Array<ConsoleArgDesc>, callb : Dynamic ) {
 		commands.set(name, { help : help == null ? "" : help, args:args, callb:callb } );
 	}
 
 	#end
-
+	
+	/**
+		Add a new command to console. <span class="label">Macro method</span>
+
+		The `callb` method arguments are used to determine console argument type and names. Due to that, 
+		only the following callback argument types are supported: `Int`, `Float`, `String` and `Bool`.
+		Another limitation is that commands added via macro do not contain description.
+
+		For example:
+		```haxe
+		function addItem(id:Int, ?amount:Int) {
+			var item = findItemById(id)
+			if (amount == null) amount = 1;
+			player.giveItem(item, amount);
+			console.log('Added $amount x ${item.name} to player!');
+		}
+		// Macro call automatically takes addItem arguments.
+		console.add("additem", addItem);
+		// And is equivalent to using addCommand describing each argument manually:
+		console.addCommand("additem", null, [{ name: "id", t: AInt }, { name: "amount", t: AInt, opt: true }], addItem);
+		```
+
+		@param name A String expression of the command name.
+		@param callb An expression that points at the callback method.
+	**/
 	public macro function add( ethis, name, callb ) {
 		var args = [];
 		var et = haxe.macro.Context.typeExpr(callb);
@@ -106,10 +195,18 @@ class Console #if !macro extends h2d.Object #end {
 
 	#if !macro
 
+	/**
+		Add an alias to an existing command.
+		@param name Command alias.
+		@param command Full command name to alias.
+	**/
 	public function addAlias( name, command ) {
 		aliases.set(name, command);
 	}
 
+	/**
+		Executes `commandLine` the same way the user would execute it.
+	**/
 	public function runCommand( commandLine : String ) {
 		handleCommand(commandLine);
 	}
@@ -179,10 +276,16 @@ class Console #if !macro extends h2d.Object #end {
 		}
 	}
 
+	/**
+		Checks if the Console is currently shown.
+	**/
 	public function isActive() {
 		return bg.visible;
 	}
 
+	/**
+		Hides the Console.
+	**/
 	public function hide() {
 		bg.visible = false;
 		tf.text = "";
@@ -190,6 +293,9 @@ class Console #if !macro extends h2d.Object #end {
 		tf.cursorIndex = -1;
 	}
 
+	/**
+		Shows and focuses the Console.
+	**/
 	public function show() {
 		bg.visible = true;
 		tf.focus();
@@ -409,6 +515,11 @@ class Console #if !macro extends h2d.Object #end {
 		}
 	}
 
+	/**
+		Print to the console log.
+		@param text The text to show in the log message.
+		@param color Optional custom text color.
+	**/
 	public function log( text : String, ?color ) {
 		if( color == null ) color = tf.textColor;
 		var oldH = logTxt.textHeight;
@@ -443,4 +554,4 @@ class Console #if !macro extends h2d.Object #end {
 
 	#end
 
-}
+}

+ 26 - 11
h2d/Drawable.hx

@@ -1,24 +1,30 @@
 package h2d;
 
 /**
-	h2d.Drawable is the base class for all 2D objects that will draw something on screen.
+	A base class for all 2D objects that will draw something on the screen.
+
 	Unlike Object base class, all properties of Drawable only apply to the current object and are not inherited by its children.
 **/
 class Drawable extends Object {
 
 	/**
-		The color multiplier for the object. Can be used to adjust individually each of the four channels R,G,B,A (default [1,1,1,1])
+		The color multiplier for the drawable. Can be used to adjust individually each of the four channels R,G,B,A (default [1,1,1,1])
 	**/
 	public var color(default,default) : h3d.Vector;
 
 	/**
-		By enabling smoothing, scaling the object up or down will use hardware bilinear filtering resulting in less crisp aspect.
-		By default smooth is null and then Scene.defaultSmooth value is used.
+		By enabling smoothing, scaling the object up or down will use hardware bilinear filtering resulting in a less crisp aspect.
+
+		By default smooth is `null` in which case `Scene.defaultSmooth` value is used.
 	**/
 	public var smooth : Null<Bool>;
 
 	/**
-		By enabling tile wrapping, you can have tiles which size exceed the texture size and will repeat instead of displaying clamped pixels.
+		Enables texture uv wrap for this Drawable, causing tiles with uv exceeding the texture size to repeat instead of clamping on edges.
+		
+		Note that `tileWrap` does not use the `Tile` region as a wrapping area but instead uses underlying `h3d.mat.Texture` size.
+		This is due to implementation specifics, as it just sets the `Texture.wrap` to either `Repeat` or `Clamp`.
+		Because of that, proper Tile tiling can be expected only when the tile covers an entire Texture area.
 	**/
 	public var tileWrap(default, set) : Bool;
 
@@ -39,6 +45,10 @@ class Drawable extends Object {
 
 	var shaders : hxsl.ShaderList;
 
+	/**
+		Create a new Drawable instance with given parent.
+		@param parent An optional parent `h2d.Object` instance to which Drawable adds itself if set.
+	**/
 	function new(parent : h2d.Object) {
 		super(parent);
 		color = new h3d.Vector(1, 1, 1, 1);
@@ -91,7 +101,8 @@ class Drawable extends Object {
 	}
 
 	/**
-		Set the `colorMatrix` value by specifying which effects to apply. Calling adjustColor() reset the colorMatrix to `null`
+		Set the `Drawable.colorMatrix` value by specifying which effects to apply.
+		Calling `adjustColor()` without arguments will reset the colorMatrix to `null`.
 	**/
 	public function adjustColor( ?col : h3d.Matrix.ColorAdjust ) : Void {
 		if( col == null )
@@ -129,7 +140,8 @@ class Drawable extends Object {
 	}
 
 	/**
-		Return the built shader code, can be used for debugging shader assembly
+		Returns the built shader code, can be used for debugging shader assembly
+		@param toHxsl Whether return an HXSL shader or the native shading language of the backend.
 	**/
 	public function getDebugShaderCode( toHxsl = true ) {
 		var shader = @:privateAccess {
@@ -145,7 +157,8 @@ class Drawable extends Object {
 	}
 
 	/**
-		Return the first shader of the given shader class among the object shaders
+		Returns the first shader of the given shader class among the drawable shaders.
+		@param stype The class of the shader to look up.
 	**/
 	public function getShader< T:hxsl.Shader >( stype : Class<T> ) : T {
 		if (shaders != null) for( s in shaders ) {
@@ -157,14 +170,16 @@ class Drawable extends Object {
 	}
 
 	/**
-		Return all object shaders
+		Returns an iterator of all drawable shaders
 	**/
 	public inline function getShaders() {
 		return shaders.iterator();
 	}
 
 	/**
-		Add a shader to the object shaders
+		Add a shader to the drawable shaders.
+
+		Keep in mind, that as stated before, drawable children do not inherit Drawable properties, which includes shaders.
 	**/
 	public function addShader<T:hxsl.Shader>( s : T ) : T {
 		if( s == null ) throw "Can't add null shader";
@@ -173,7 +188,7 @@ class Drawable extends Object {
 	}
 
 	/**
-		Remove a shader from the object shaders, returns true if found or false if it was not part of our shaders.
+		Remove a shader from the drawable shaders, returns true if found or false if it was not part of our shaders.
 	**/
 	public function removeShader( s : hxsl.Shader ) {
 		var prev = null, cur = shaders;

+ 69 - 3
h2d/Dropdown.hx

@@ -30,24 +30,67 @@ private class Fake extends Object {
 	}
 }
 
+/**
+	A simple UI component that creates an interactive drop-down list.
+	
+	Dropdown will add an `h2d.Flow` to the `Scene` when opening in order to be visible above other objects. See `Dropdown.dropdownLayer` for more details.
+
+	There is no handling of user input on items, and implementation of selection and other actions is up to the user.
+
+	Note that when `dropdownList` opens and closes, item objects will receive the `onHierarchyChanged` callback.
+**/
 class Dropdown extends Flow {
 	var items : Array<h2d.Object>;
 	var fake : Fake;
 	var cursor : h2d.Bitmap;
 	var arrow : h2d.Bitmap;
 
+	/**
+		A background Tile that is shown when user hover over an item in the dropdown list.
+
+		The tile will be stretched to cover full row width and item height during rendering.
+	**/
 	public var tileOverItem(default, set) : h2d.Tile;
+	/**
+		A Tile used to visualize an arrow of the dropdown when the list is closed.
+	**/
 	public var tileArrow(default, set) : h2d.Tile;
+	/**
+		A Tile used to visualize and arrow of the dropdown when the list is open.
+	**/
 	public var tileArrowOpen : h2d.Tile;
-
+	
+	/**
+		When disabled, the user would not be able to change the selected item.
+	**/
 	public var canEdit(default,set) : Bool = true;
+	/**
+		A reference to the Flow that will contain the items.
+
+		Adding objects to this Flow will not automatically add them to the item list, use `Dropdown.addItem` instead.
+	**/
 	public var dropdownList : Flow;
+	/**
+		A Scene layer to which `dropdownList` will be added when opening dropdown.
+	**/
 	public var dropdownLayer : Int = 0;
+	/**
+		Currently selected item index. To deselect an item, set it to `-1`.
+	**/
 	public var selectedItem(default, set) : Int = -1;
+	/**
+		Currently highlighted item index.
+	**/
 	public var highlightedItem(default, null) : Int = -1;
-
+	/**
+		When enabled, the dropdown list will appear above the dropdown.
+	**/
 	public var rollUp : Bool = false;
 
+	/**
+		Create a new Dropdown with given parent.
+		@param parent An optional parent `h2d.Object` instance to which Dropdown adds itself if set.
+	**/
 	public function new(?parent) {
 		super(parent);
 
@@ -157,6 +200,9 @@ class Dropdown extends Flow {
 		return tileOverItem = t;
 	}
 
+	/**
+		Adds the Object `s` to the dropdown list. `s` is not restricted to be the same type across all items.
+	**/
 	public function addItem(s : Object) {
 		items.push(s);
 		dropdownList.addChild(s);
@@ -183,6 +229,9 @@ class Dropdown extends Flow {
 		return selectedItem = s;
 	}
 
+	/**
+		Programmatically opens the dropdown, showing the dropdown list.
+	**/
 	public function open() {
 		if( dropdownList.parent == this ) {
 			getScene().add(dropdownList, dropdownLayer);
@@ -192,6 +241,9 @@ class Dropdown extends Flow {
 		}
 	}
 
+	/**
+		Programmatically closes the dropdown, hiding the dropdown list.
+	**/
 	public function close() {
 		if( dropdownList.parent != this ) {
 			addChild(dropdownList);
@@ -207,15 +259,29 @@ class Dropdown extends Flow {
 			dropdownList.remove();
 	}
 
+	/**
+		Sent when dropdown is being opened. Triggered both by user input and programmatic action via `Dropdown.open`.
+	**/
 	public dynamic function onOpen() {
 	}
 
+	/**
+		Sent when dropdown is being closed. Triggered both by user input and programmatic action via `Dropdown.close`.
+	**/
 	public dynamic function onClose() {
 	}
 
+	/**
+		Sent when user hovers over an item in the dropdown list.
+		@param item An object that was hovered.
+	**/
 	public dynamic function onOverItem(item : Object) {
 	}
 
+	/**
+		Sent when user moves mouse away from an item in the dropdown list.
+		@param item An item that was hovered previously.
+	**/
 	public dynamic function onOutItem(item : Object) {
 	}
-}
+}

+ 271 - 37
h2d/Flow.hx

@@ -1,73 +1,196 @@
 package h2d;
 
+/**
+	`Flow` content alignment rules.
+**/
 enum FlowAlign {
+	/**
+		Aligns children to the top edge of the `Flow`.
+
+		Only applicable to the `Flow.verticalAlign`.
+	**/
 	Top;
+	/**
+		Aligns children to the left edge of the `Flow`.
+
+		Only applicable to the `Flow.horizontalAlign`.
+	**/
 	Left;
+	/**
+		Aligns children to the right edge of the `Flow`.
+
+		Only applicable to the `Flow.horizontalAlign`.
+	**/
 	Right;
+	/**
+		Aligns children to the center of the `Flow`.
+	**/
 	Middle;
+	/**
+		Aligns children to the bottom edge of the `Flow`.
+
+		Only applicable to the `Flow.verticalAlign`.
+	**/
 	Bottom;
 }
 
+/**
+	The `Flow.layout` type.
+**/
 enum FlowLayout {
+	/**
+		Children are aligned horizontally from left to right (or right to left when `Flow.reverse` is enabled).
+		
+		If `Flow.multiline` is enabled - children can overflow to the next row if there is not enough space available within the Flow size constraints.
+
+		`Flow.lineHeight` can be used to set a fixed row height when `Flow.overflow` is set to `Limit` or `Hidden`.
+		Objects with height that exceed the limitation will be aligned according to `Flow.verticalAlign` value vertically with `null` being treated as `Bottom`.
+	**/
 	Horizontal;
+	/**
+		Children are aligned vertically from top to bottom (or bottom to top when `Flow.reverse` is enabled).
+
+		If `Flow.multiline` is enabled - children can overflow to the next column if there is not enough space available within the Flow size constraints.
+
+		`Flow.colWidth` can be used to set a fixed column width when `Flow.overflow` is set to `Limit` or `Hidden`.
+		Objects with height that exceed the limitation will be aligned according to `Flow.horizontalAlign` value horizontally with `null` being treated as `Left`.
+	**/
 	Vertical;
+	/**
+		Children are aligned independently (`Flow.reverse` has no effect).
+	**/
 	Stack;
 }
 
+/**
+	The `Flow.overflow` rules.
+**/
 enum FlowOverflow {
 	/**
-		Children larger than `maxWidth`/`maxHeight` will expand the flow size.
+		Children larger than `Flow.maxWidth` / `Flow.maxHeight` will expand the flow size.
 	**/
 	Expand;
 	/**
-		Limits the bounds reported by the flow using `maxWidth` or `maxHeight`, if set.
-		This is means children larger than max size will draw outside of their parent bounds.
+		Limits the bounds reported by the flow using `Flow.maxWidth` or `Flow.maxHeight`, if set.
+
+		Children larger than max size will draw outside of the Flow bounds or overflow if `Flow.multiline` is enabled.
 	**/
 	Limit;
 	/**
-		Limits the bounds reported by the flow using `maxWidth` or `maxHeight`, if set.
-		Compared to `Limit` - Flow will mask out children that are outside of Flow bounds.
+		Limits the bounds reported by the flow using `Flow.maxWidth` or `Flow.maxHeight`, if set.
+
+		Compared to `Limit` - Flow will mask out the content that is outside of Flow bounds.
 	**/
 	Hidden;
 	// TODO: Scroll overflow, see #606
 	//Scroll;
 }
 
+/**
+	An individual `Flow` element properties.
+
+	Can be obtained after adding the element to the Flow and calling `Flow.getProperties`.
+	Contains configuration unique of each Flow element.
+**/
 @:allow(h2d.Flow)
 class FlowProperties {
 
 	var elt : Object;
-
+	
+	/**
+		An extra padding to the left of the flow element.
+	**/
 	public var paddingLeft = 0;
+	/**
+		An extra padding to the top of the flow element.
+	**/
 	public var paddingTop = 0;
+	/**
+		An extra padding to the right of the flow element.
+	**/
 	public var paddingRight = 0;
+	/**
+		An extra padding to the bottom of the flow element.
+	**/
 	public var paddingBottom = 0;
 
+	/**
+		When enabled, element won't be automatically positioned during `Flow.reflow` and
+		instead treated as an absolute element relative to the Flow.
+	**/
 	public var isAbsolute(default,set) = false;
+	/**
+		The `Flow.horizontalAlign` override.
+
+		If `FlowProperties.isAbsolute` is enabled - aligns the element within the Flow boundaries.
+		Otherwise affects the element alignment within the Flow. Does not affect the alignment if `Flow.layout` is `Horizontal`.
+	**/
 	public var horizontalAlign : Null<FlowAlign>;
+	/**
+		The `Flow.verticalAlign` override.
+
+		If `FlowProperties.isAbsolute` is enabled - aligns the element within the Flow boundaries.
+		Otherwise affects the element alignment within the Flow. Does not affect the alignment if `Flow.layout` is `Vertical`.
+	**/
 	public var verticalAlign : Null<FlowAlign>;
 
+	/**
+		A visual offset of the element along the X axis.
+		
+		Offset does not affect the occupied space by the element, and can lead to overlapping with other elements.
+	**/
 	public var offsetX = 0;
+	/**
+		A visual offset of the element along the Y axis.
+		
+		Offset does not affect the occupied space by the element, and can lead to overlapping with other elements.
+	**/
 	public var offsetY = 0;
 
+	/**
+		The minimum occupied width of the element within the flow.
+	**/
 	public var minWidth : Null<Int>;
+	/**
+		The minimum occupied height of the element within the flow.
+	**/
 	public var minHeight : Null<Int>;
 
+	/**
+		The calculated element width since last element reflow.
+	**/
 	public var calculatedWidth(default,null) : Int = 0;
+	/**
+		The calculated element height since last element reflow.
+	**/
 	public var calculatedHeight(default,null) : Int = 0;
 
+	/**
+		Whether this element is the last on its current row/column, and the next flow element being on the next row/column after overflow.
+	**/
 	public var isBreak(default,null) : Bool;
+	/**
+		Forces this element to break the line and flow onto the next row/column.
+		`Flow.multiline` is not required to be enabled.
+	**/
 	public var lineBreak = false;
 
 	/**
-		If our flow have a maximum size, it will constraint the children by using .constraintSize()
+		Will constraint the element size through `Object.constraintSize` if the Flow have a set maximum size.
+
+		@see `Flow.maxWidth`
+		@see `Flow.maxHeight`
 	**/
 	public var constraint = true;
 
+	@:dox(hide)
 	public function new(elt) {
 		this.elt = elt;
 	}
 
+	/**
+		Shortcut to set both `FlowProperties.verticalAlign` and `FlowProperties.horizontalAlign`.
+	**/
 	public inline function align(vertical, horizontal) {
 		this.verticalAlign = vertical;
 		this.horizontalAlign = horizontal;
@@ -83,120 +206,222 @@ class FlowProperties {
 
 }
 
+/**
+	An automatic layout system.
+**/
 class Flow extends Object {
 
 	var tmpBounds = new h2d.col.Bounds();
 
 	/**
 		If some sub element gets resized, you need to set reflow to true in order to force
-		the reflow of elements. You can also directly call reflow() which will immediately
+		the reflow of elements. You can also directly call `Flow.reflow` which will immediately
 		update all elements positions.
 
-		If a reflow is needed, reflow() will be called before rendering the flow.
+		If a reflow is needed, `Flow.reflow` will be called before rendering the flow.
 		Each change in one of the flow properties or addition/removal of elements will set needReflow to true.
 	**/
 	public var needReflow(default, set) : Bool = true;
 
 	/**
 		Horizontal alignment of elements inside the flow.
+		See `FlowAlign` for more details.
 	**/
 	public var horizontalAlign(default, set) : Null<FlowAlign>;
 
 	/**
 		Vertical alignment of elements inside the flow.
+		See `FlowAlign` for more details.
 	**/
 	public var verticalAlign(default,set) : Null<FlowAlign>;
 
+	/**
+		Ensures that Flow is at least the specified outer width at all times when not null.
+	**/
 	public var minWidth(default, set) : Null<Int>;
+	/**
+		Ensures that Flow is at least the specified outer height at all times when not null.
+	**/
 	public var minHeight(default, set) : Null<Int>;
+	/**
+		Attempts to limit the Flow outer width to the specified width.
+		Used as a baseline for overflow when `Flow.multiline` is enabled and `Flow.layout` is `Horizontal`.
+	**/
 	public var maxWidth(default, set) : Null<Int>;
+	/**
+		Attempts to limit the Flow outer height to the specified height.
+		Used as a baseline for overflow when `Flow.multiline` is enabled and `Flow.layout` is `Vertical`.
+	**/
 	public var maxHeight(default, set) : Null<Int>;
 
+	/**
+		Sets the minimum row height when `Flow.layout` is `Horizontal`.
+	**/
 	public var lineHeight(default, set) : Null<Int>;
+	/**
+		Sets the minimum colum width when `Flow.layout` is `Vertical`.
+	**/
 	public var colWidth(default, set) : Null<Int>;
 
 	/**
 		Enabling overflow will treat maxWidth/maxHeight and lineHeight/colWidth constraints as absolute : bigger elements will overflow instead of expanding the limit.
+		See respective `FlowOverflow` values for more details.
 	**/
 	public var overflow(default, set) : FlowOverflow = Expand;
 
 	/**
 		Will set all padding values at the same time.
+
+		Note that padding is applied inside the flow boundaries and included in the size constraint, shrinking available space for Flow children.
+
+		@see `Flow.paddingLeft`
+		@see `Flow.paddingRight`
+		@see `Flow.paddingTop`
+		@see `Flow.paddingBottom`
+		@see `Flow.paddingHorizontal`
+		@see `Flow.paddingVertical`
 	**/
 	public var padding(never, set) : Int;
+	/**
+		Will set `Flow.paddingLeft` and `Flow.paddingRight` to the given value.
+
+		Note that padding is applied inside the flow boundaries and included in the size constraint, shrinking available space for Flow children.
+	**/
 	public var paddingHorizontal(never, set) : Int;
+	/**
+		Will set `Flow.paddingTop` and `Flow.paddingBottom` to the given value.
+
+		Note that padding is applied inside the flow boundaries and included in the size constraint, shrinking available space for Flow children.
+	**/
 	public var paddingVertical(never, set) : Int;
+	/**
+		Sets the extra padding along the left edge of the Flow.
+
+		Note that padding is applied inside the flow boundaries and included in the size constraint, shrinking available space for Flow children.
+	**/
 	public var paddingLeft(default, set) : Int = 0;
+	/**
+		Sets the extra padding along the right edge of the Flow.
+
+		Note that padding is applied inside the flow boundaries and included in the size constraint, shrinking available space for Flow children.
+	**/
 	public var paddingRight(default, set) : Int = 0;
+	/**
+		Sets the extra padding along the top edge of the Flow.
+
+		Note that padding is applied inside the flow boundaries and included in the size constraint, shrinking available space for Flow children.
+	**/
 	public var paddingTop(default, set) : Int = 0;
+	/**
+		Sets the extra padding along the bottom edge of the Flow.
+
+		Note that padding is applied inside the flow boundaries and included in the size constraint, shrinking available space for Flow children.
+	**/
 	public var paddingBottom(default, set) : Int = 0;
 
 	/**
-		The horizontal space between two flowed elements.
+		The horizontal separation spacing between two flowed elements.
 	**/
 	public var horizontalSpacing(default, set) : Int = 0;
 
 	/**
-		The vertical space between two flowed elements.
+		The vertical separation spacing between two flowed elements.
 	**/
 	public var verticalSpacing(default, set) : Int = 0;
 
 	/**
-		Set enableInteractive to true to create an h2d.Interactive accessible through
-		the interactive field which will automatically cover the whole Flow area.
+		Adds an `h2d.Interactive` to the Flow that is accessible through `Flow.interactive` field.
+		This Interactive is automatically resized to cover the whole Flow area.
+
+		Flow is added as a bottom-most (after the `Flow.backgroundTile`) child as to not impede flow elements with Interactives.
 	**/
 	public var enableInteractive(default, set) : Bool;
 
 	/**
-		See enableInteractive.
+		@see `Flow.enableInteractive`.
 	**/
 	public var interactive(default, null) : h2d.Interactive;
 
 	/**
-		Setting a background tile will create a ScaleGrid background which uses the borderWidth/Height values for its borders.
+		Setting a background tile will create an `h2d.ScaleGrid` background which uses the `Flow.borderWidth`/`Flow.borderHeigh` values for its borders.
+
 		It will automatically resize when the reflow is done to cover the whole Flow area.
 	**/
 	public var backgroundTile(default, set) : h2d.Tile;
+	/**
+		Horizontal border width of the `Flow.backgroundTile`.
+
+		Does not affect padding by default, which can be enabled with `-D flow_border` compilation flag.
+		If border padding is enabled, `Flow.outerWidth` will be affected accordingly even if background tile is not set
+		and will follow the same constraint limitation as padding.
+		
+		@see `Flow.paddingLeft`
+		@see `Flow.paddingRight`
+		@see `Flow.paddingHorizontal`
+		@see `h2d.ScaleGrid.borderWidth`
+	**/
 	public var borderWidth(default, set) : Int = 0;
+	/**
+		Vertical border width of the `Flow.backgroundTile`.
+
+		Does not affect padding by default, which can be enabled with `-D flow_border` compilation flag.
+		If border padding is enabled, `Flow.outerHeight` will be affected accordingly even if background tile is not set
+		and will follow the same constraint limitation as padding.
+
+		@see `Flow.paddingTop`
+		@see `Flow.paddingBottom`
+		@see `Flow.paddingVertical`
+		@see `h2d.ScaleGrid.borderHeight`
+	**/
 	public var borderHeight(default, set) : Int = 0;
 
 	/**
-		Calculate the client width, which is the innner size of the flow without the borders and padding.
+		Calculate the client width, which is the inner size of the flow without the borders and padding.
+
+		@see `Flow.padding`
 	**/
 	public var innerWidth(get, never) : Int;
 	/**
-		Calculate the client height, which is the innner size of the flow without the borders and padding.
+		Calculate the client height, which is the inner size of the flow without the borders and padding.
+
+		@see `Flow.padding`
 	**/
 	public var innerHeight(get, never) : Int;
 
 	/**
-		Flow total width (inlcudes borders and paddings)
+		Flow total width. Compared to `Flow.innerWidth`, it also includes paddings and, if enabled, borders (see `Flow.borderWidth`).
+
+		@see `Flow.padding`
 	**/
 	public var outerWidth(get, never) : Int;
 	/**
-		Flow total height (inlcudes borders and paddings)
+		Flow total height Compared to `Flow.innerHeight`, it also includes paddings and, if enabled, borders (see `Flow.borderHeight`).
+
+		@see `Flow.padding`
 	**/
 	public var outerHeight(get, never) : Int;
 
 	/**
-		When set to `Horizontal` (default), children are aligned horizontally from left to right (right to left using `reverse`).
-		When set to `Vertical`, children are aligned vertically from tom to bottom (bottom to top using `reverse`).
-		When set to `Stack`, children are aligned independently (`reverse` has no effect).
-		Both `Horizontal` and `Vertical` alignments can overflow to the next row/column if the available space is constrained.
+		The Flow item layout rules.
+		See `FlowLayout` for specific details on each mode.
 	**/
 	public var layout(default, set) : FlowLayout = Horizontal;
 
 	@:deprecated("isVertical is replaced by layout=Vertical")
+	@:dox(hide)
 	public var isVertical(get, set) : Bool;
 
 	/**
 		When isInline is set to false, the flow size will be reported based on its bounds instead of its calculated size.
-		See getSize() documentation.
+		@see `Object.getSize`
 	**/
 	public var isInline = true;
 
 	/**
-		When set to true, the debug will display red box around the flow, green box for the client space and blue boxes for each element.
+		When set to true, the Flow will display a debug overlay.
+		* Red box around the flow
+		* Green box for the client space.
+		* Blue boxes for each element.
 	**/
 	public var debug(default, set) : Bool;
 
@@ -206,17 +431,18 @@ class Flow extends Object {
 	public var multiline(default,set) : Bool = false;
 
 	/**
-		When set to true, children are aligned in reverse order
+		When set to true, children are aligned in reverse order.
+
+		Note that it does not affect render ordering, and may cause overlap of elements due to them positioned in reverse order.
 	**/
 	public var reverse(default,set) : Bool = false;
 
 	/**
-		When set to true, if a width constraint is present and `minWidth` is null, will expand to fill all the available horizontal space
+		When set to true, if a width constraint is present and `minWidth` is null - Flow will expand to fill all the available horizontal space
 	**/
-
 	public var fillWidth(default,set) : Bool = false;
 	/**
-		When set to true, if a height constraint is present and `minHeight` is null, will expand to fill all the available vertical space
+		When set to true, if a height constraint is present and `minHeight` is null - Flow will expand to fill all the available vertical space
 	**/
 	public var fillHeight(default,set) : Bool = false;
 
@@ -234,12 +460,18 @@ class Flow extends Object {
 	var realMinHeight : Int = -1;
 	var isConstraint : Bool;
 
+	/**
+		Create a new Flow instance.
+		@param parent An optional parent `h2d.Object` instance to which Flow adds itself if set.
+	**/
 	public function new(?parent) {
 		super(parent);
 	}
 
 	/**
-		Get the per-element properties. Returns null if the element is not currently part of the flow.
+		Get the per-element properties. Returns null if the element is not currently part of the Flow.
+
+		Requesting the properties will cause a reflow regardless if properties values were changed or not.
 	**/
 	public function getProperties( e : h2d.Object ) {
 		needReflow = true; // properties might be changed
@@ -429,8 +661,10 @@ class Flow extends Object {
 
 	/**
 		Adds some spacing by either increasing the padding of the latest
-		non absolute element or the padding of the flow if no element was found.
-		The padding affected depends on the isVertical property.
+		non-absolute element or the padding of the flow if there are no elements in it.
+
+		The padding affected depends on the `Flow.layout` mode.
+		It's impossible to add spacing with a `Stack` Flow layout.
 	**/
 	public function addSpacing( v : Int ) {
 		var last = properties.length - 1;
@@ -472,7 +706,7 @@ class Flow extends Object {
 
 	override function setParentContainer(c) {
 		parentContainer = c;
-		// break propogation
+		// break propagation
 	}
 
 	override function addChildAt( s, pos ) {
@@ -670,7 +904,7 @@ class Flow extends Object {
 
 	/**
 		Call to force all flowed elements position to be updated.
-		See needReflow for more informations.
+		See `Flow.needReflow` for more information.
 	**/
 	public function reflow() {
 
@@ -690,7 +924,7 @@ class Flow extends Object {
 
 		var isConstraintWidth = realMaxWidth >= 0;
 		var isConstraintHeight = realMaxHeight >= 0;
-		// outter size
+		// outer size
 		var maxTotWidth = realMaxWidth < 0 ? 100000000 : Math.floor(realMaxWidth);
 		var maxTotHeight = realMaxHeight < 0 ? 100000000 : Math.floor(realMaxHeight);
 		// inner size
@@ -1123,13 +1357,13 @@ class Flow extends Object {
 	}
 
 	/**
-		Called before each reflow() is done.
+		Sent at the start of the `Flow.reflow`.
 	**/
 	public dynamic function onBeforeReflow() {
 	}
 
 	/**
-		Called after each time a reflow() was done.
+		Sent after the `Flow.reflow` was finished.
 	**/
 	public dynamic function onAfterReflow() {
 	}

+ 139 - 6
h2d/Font.hx

@@ -1,32 +1,77 @@
 package h2d;
 
+/**
+	A `FontChar` kerning information as well as linked list of kernings. See `FontChar.kerning`.
+**/
 class Kerning {
+	/**
+		A character that should precede current character in order to apply this kerning.
+	**/
 	public var prevChar : Int;
+	/**
+		A kerning offset between the character pair in pixels.
+	**/
 	public var offset : Float;
+	/**
+		The next kerning reference.
+	**/
 	public var next : Null<Kerning>;
+
+	/**
+		Create a new kerning instance.
+		@param c The preceding character.
+		@param o The kerning offset.
+	**/
 	public function new(c, o) {
 		this.prevChar = c;
 		this.offset = o;
 	}
 }
 
+/**
+	A single `Font` character descriptor.
+**/
 class FontChar {
-
+	/**
+		A Tile representing position of a character on the texture.
+	**/
 	public var t : h2d.Tile;
+	/**
+		Horizontal advance value of the character.
+
+		On top of advance, letter spacing is affected by `FontChar.kerning` matches and `Text.letterSpacing`.
+	**/
 	public var width : Float;
+	/**
+		Linked list of kerning values.
+
+		In order to add new kerning values use `FontChar.addKerning` and `FontChar.getKerningOffset` to retrieve kerning offsets.
+	**/
+	@:dox(show)
 	var kerning : Null<Kerning>;
 
+	/**
+		Create a new font character.
+		@param t The character Tile.
+		@param width The horizontal advance of the character.
+	**/
 	public function new(t,w) {
 		this.t = t;
 		this.width = w;
 	}
 
+	/**
+		Adds a new kerning to the character with specified `prevChar` and `offset`.
+	**/
 	public function addKerning( prevChar : Int, offset : Int ) {
 		var k = new Kerning(prevChar, offset);
 		k.next = kerning;
 		kerning = k;
 	}
 
+	/**
+		Returns kerning offset for a pair `[prevChar, currentChar]` or `0` if there was no paired kerning value.
+	**/
 	public function getKerningOffset( prevChar : Int ) {
 		var k = kerning;
 		while( k != null ) {
@@ -37,6 +82,9 @@ class FontChar {
 		return 0;
 	}
 
+	/**
+		Clones the character instance.
+	**/
 	public function clone() {
 		var c = new FontChar(t.clone(), width);
 		// Clone entire kerning tree in case Font got resized.
@@ -56,7 +104,9 @@ class FontChar {
 
 }
 
-/** Channel reading method for SDF. **/
+/**
+	Channel reading method for `FontType.SignedDistanceField`.
+**/
 @:enum abstract SDFChannel(Int) from Int to Int {
 	/** Use red channel of a texture to determine distance. **/
 	var Red = 0;
@@ -70,21 +120,70 @@ class FontChar {
 	var MultiChannel = 4;
 }
 
+/**
+	The rendering type of the of the `Font` instance.
+**/
 enum FontType {
+	/**
+		A simple raster bitmap font.
+	**/
 	BitmapFont;
-	/** Signed Distance Field font. Channel indexes are in RGBA order. See here for info: https://github.com/libgdx/libgdx/wiki/Distance-field-fonts **/
+	/**
+		A Signed Distance Field font data. Each glyph pixel contains the distance to the closest glyph edge instead of actual color.
+
+		To render an SDF font, `Text` utilizes `h3d.shader.SignedDistanceField` shader to produce smoothed and scalable text.
+		Because shader expects texture to use bilinear filtering, Text automatically enables `Drawable.smooth` on itself.
+
+		See [Text](https://github.com/HeapsIO/heaps/wiki/Text) manual and [libgdx wiki](https://github.com/libgdx/libgdx/wiki/Distance-field-fonts) for more details.
+
+		@param channel The channel that serves as distance data source.
+		@param alphaCutoff The distance value that is considered to be the edge. Usually should be 0.5.
+		@param smoothing The smoothing of edge. Lower value lead to sharper edges.
+	**/
 	SignedDistanceField(channel : SDFChannel, alphaCutoff : Float, smoothing : Float);
 }
 
-class Font {
+/**
+	An instance of a text font.
 
+	Heaps comes with a default Font that covers basic ASCII characters, and can be retrieved via `hxd.res.DefaultFont.get()`.
+**/
+class Font {
+	/**
+		The font name. Assigned on font creation and can be used to identify font instances.
+	**/
 	public var name(default, null) : String;
+	/**
+		Current font size. Font can be resized with `resizeTo`.
+	**/
 	public var size(default, null) : Int;
+	/**
+		The baseline value of the font represents the base on which characters will sit.
+
+		Used primarily with `HtmlText` to sit multiple fonts and images at the same line.
+	**/
 	public var baseLine(default, null) : Float;
+	/**
+		Font line height provides vertical offset for each new line of the text.
+	**/
 	public var lineHeight(default, null) : Float;
+	/**
+		Reference to the source Tile containing all glyphs of the Font.
+	**/
 	public var tile(default,null) : h2d.Tile;
+	/**
+		The resource path of the source Tile. Either relative to .fnt or to resources root.
+	**/
 	public var tilePath(default,null) : String;
+	/**
+		The font type. BitmapFonts rendered as-is, but SDF fonts will use an extra shader to produce scalable smooth fonts.
+		See `FontType.SignedDistanceField` for more details.
+	**/
 	public var type : FontType;
+	/**
+		Font charset allows to resolve specific char codes that are not directly present in glyph map as well as detect spaces.
+		Defaults to `hxd.Charset.getDefault()`.
+	**/
 	public var charset : hxd.Charset;
 	var glyphs : Map<Int,FontChar>;
 	var nullChar : FontChar;
@@ -93,6 +192,12 @@ class Font {
 	var offsetX:Float = 0;
 	var offsetY:Float = 0;
 
+	/**
+		Creates an empty font instance with specified parameters.
+		@param name The name of the font.
+		@param size Initial size of the font.
+		@param type The font type.
+	**/
 	function new(name : String, size : Int, ?type : FontType) {
 		this.name = name;
 		this.size = size;
@@ -108,6 +213,12 @@ class Font {
 			this.type = type;
 	}
 
+	/**
+		Returns a `FontChar` instance corresponding to the `code`.
+		If font char is not present in glyph list, `charset.resolveChar` is called.
+		Returns `null` if glyph under specified charcode does not exist.
+		@param code The charcode to search for.
+	**/
 	public inline function getChar( code : Int ) {
 		var c = glyphs.get(code);
 		if( c == null ) {
@@ -118,6 +229,12 @@ class Font {
 		return c;
 	}
 
+	/**
+		Offsets all glyphs by specified amount.
+		Affects each glyph `Tile.dx` and `Tile.dy`.
+		@param x The X offset of the glyphs.
+		@param y The Y offset of the glyphs.
+	**/
 	public function setOffset( x : Float, y :Float ) {
 		var dx = x - offsetX;
 		var dy = y - offsetY;
@@ -130,6 +247,9 @@ class Font {
 		this.offsetY += dy;
 	}
 
+	/**
+		Creates a copy of the font instance.
+	**/
 	public function clone() {
 		var f = new Font(name, size);
 		f.baseLine = baseLine;
@@ -149,7 +269,12 @@ class Font {
 	}
 
 	/**
-		This is meant to create smoother fonts by creating them with double size while still keeping the original glyph size.
+		Resizes the Font instance to specified size.
+
+		For BitmapFonts it can be used to create smoother fonts by rasterizing them with double size while still keeping the original glyph size by downscaling the font.
+		And SDF fonts can be resized to arbitrary sizes to produce scalable fonts of any size.
+
+		@param size The new font size.
 	**/
 	public function resizeTo( size : Int ) {
 		var ratio = size / initSize;
@@ -169,10 +294,18 @@ class Font {
 		this.size = size;
 	}
 
-	public function hasChar( code : Int ) {
+	/**
+		Checks if character is present in glyph list.
+		Compared to `getChar` does not check if it exists through `Font.charset`.
+		@param code The charcode to look up.
+	**/
+	public function hasChar( code : Int ) : Bool {
 		return glyphs.get(code) != null;
 	}
 
+	/**
+		Disposes of the Font instance. Equivalent to `Tile.dispose`.
+	**/
 	public function dispose() {
 		tile.dispose();
 	}

+ 151 - 0
h2d/Graphics.hx

@@ -4,6 +4,7 @@ import hxd.impl.Allocator;
 
 private typedef GraphicsPoint = hxd.poly2tri.Point;
 
+@:dox(hide)
 class GPoint {
 	public var x : Float;
 	public var y : Float;
@@ -144,6 +145,15 @@ private class GraphicsContent extends h3d.prim.Primitive {
 
 }
 
+/**
+	A simple interface to draw arbitrary 2D geometry.
+
+	Usage notes:
+	* While Graphics allows for multiple unique textures, each texture swap causes a new drawcall,
+	and due to that it's recommended to minimize the amount of used textures per Graphics instance,
+	ideally limiting to only one texture.
+	* Due to how Graphics operate, removing them from the active `h2d.Scene` will cause a loss of all data.
+**/
 class Graphics extends Drawable {
 
 	var content : GraphicsContent;
@@ -172,9 +182,22 @@ class Graphics extends Drawable {
 	var mx : Float = 0.;
 	var my : Float = 0.;
 
+	/**
+		The Tile used as source of Texture to render.
+	**/
 	public var tile : h2d.Tile;
+	/**
+		Adds bevel cut-off at line corners.
+
+		The value is a percentile in range of 0...1, dictating at which point edges get beveled based on their angle.
+		Value of 0 being not beveled and 1 being always beveled.
+	**/
 	public var bevel = 0.25; //0 = not beveled, 1 = always beveled
 
+	/**
+		Create a new Graphics instance.
+		@param parent An optional parent `h2d.Object` instance to which Graphics adds itself if set.
+	**/
 	public function new(?parent) {
 		super(parent);
 		content = new GraphicsContent();
@@ -187,6 +210,9 @@ class Graphics extends Drawable {
 		clear();
 	}
 
+	/**
+		Clears the Graphics contents.
+	**/
 	public function clear() {
 		content.clear();
 		tmpPoints = [];
@@ -395,6 +421,14 @@ class Graphics extends Drawable {
 		tmpPoints = [];
 	}
 
+	/**
+		Begins a solid color fill.
+
+		Beginning new fill will finish previous fill operation without need to call `Graphics.endFill`.
+
+		@param color An RGB color with which to fill the drawn shapes.
+		@param alpha A transparency of the fill color.
+	**/
 	public function beginFill( color : Int = 0, alpha = 1.  ) {
 		flush();
 		setColor(color,alpha);
@@ -404,6 +438,19 @@ class Graphics extends Drawable {
 	/**
 		Position a virtual tile at the given position and scale. Every draw will display a part of this tile relative
 		to these coordinates.
+
+		Note that in by default, Tile is not wrapped, and in order to render tiling texture, `Drawable.tileWrap` have to be set.
+		Additionally, both `Tile.dx` and `Tile.dy` are ignored (use `dx`/`dy` arguments instead)
+		as well as tile defined size of the tile through `Tile.width` and `Tile.height` (use `scaleX`/`scaleY` relative to texture size).
+
+		Beginning new fill will finish previous fill operation without need to call `Graphics.endFill`.
+
+		@param dx An X offset of the Tile relative to Graphics.
+		@param dy An Y offset of the Tile relative to Graphics.
+		@param scaleX A horizontal scale factor applied to the Tile texture.
+		@param scaleY A vertical scale factor applied to the Tile texture.
+		@param tile The tile to fill with. If null, uses previously used Tile with `beginTileFill` or throws an error.
+		Previous tile is remembered across `Graphics.clear` calls.
 	**/
 	public function beginTileFill( ?dx : Float, ?dy : Float, ?scaleX : Float, ?scaleY : Float, ?tile : h2d.Tile ) {
 		beginFill(0xFFFFFF);
@@ -438,12 +485,28 @@ class Graphics extends Drawable {
 		my = -dy * md;
 	}
 
+	/**
+		Draws a Tile at given position.
+		See `Graphics.beginTileFill` for limitations.
+
+		This methods ends current fill operation.
+		@param x The X position of the tile.
+		@param y The Y position of the tile.
+		@param tile The tile to draw.
+	**/
 	public function drawTile( x : Float, y : Float, tile : h2d.Tile ) {
 		beginTileFill(x, y, tile);
 		drawRect(x, y, tile.width, tile.height);
 		endFill();
 	}
 
+	/**
+		Sets an outline style. Changing the line style ends the currently drawn line.
+
+		@param size Width of the outline. Setting size to 0 will remove the outline.
+		@param color An outline RGB color.
+		@param alpha An outline transparency.
+	**/
 	public function lineStyle( size : Float = 0, color = 0, alpha = 1. ) {
 		flush();
 		this.lineSize = size;
@@ -453,16 +516,29 @@ class Graphics extends Drawable {
 		lineB = (color & 0xFF) / 255.;
 	}
 
+	/**
+		Ends the current line and starts new one at given position.
+	**/
 	public inline function moveTo(x,y) {
 		flush();
 		lineTo(x, y);
 	}
 
+	/**
+		Ends the current fill operation.
+	**/
 	public function endFill() {
 		flush();
 		doFill = false;
 	}
 
+	/**
+		Changes current fill color.
+		Does not interrupt current fill operation and can be utilized to customize color per vertex.
+		During tile fill operation, color serves as a tile color multiplier.
+		@param color The new fill color.
+		@param alpha The new fill transparency.
+	**/
 	public inline function setColor( color : Int, alpha : Float = 1. ) {
 		curA = alpha;
 		curR = ((color >> 16) & 0xFF) / 255.;
@@ -470,6 +546,13 @@ class Graphics extends Drawable {
 		curB = (color & 0xFF) / 255.;
 	}
 
+	/**
+		Draws a rectangle with given parameters.
+		@param x The rectangle top-left corner X position.
+		@param y The rectangle top-left corner Y position.
+		@param w The rectangle width.
+		@param h The rectangle height.
+	**/
 	public function drawRect( x : Float, y : Float, w : Float, h : Float ) {
 		flush();
 		lineTo(x, y);
@@ -487,6 +570,15 @@ class Graphics extends Drawable {
 		flush();
 	}
 
+	/**
+		Draws a rounded rectangle with given parameters.
+		@param x The rectangle top-left corner X position.
+		@param y The rectangle top-left corner Y position.
+		@param w The rectangle width.
+		@param h The rectangle height.
+		@param radius Radius of the rectangle corners.
+		@param nsegments Amount of segments used for corners. When `0` segment count calculated automatically.
+	**/
 	public function drawRoundedRect( x : Float, y : Float, w : Float, h : Float, radius : Float, nsegments = 0 ) {
 		if (radius <= 0) {
 			return drawRect(x, y, w, h);
@@ -518,6 +610,13 @@ class Graphics extends Drawable {
 		flush();
 	}
 
+	/**
+		Draws a circle centered at given position.
+		@param cx X center position of the circle.
+		@param cy Y center position of the circle.
+		@param radius Radius of the circle.
+		@param nsegments Amount of segments used to draw the circle. When `0`, amount of segments calculated automatically.
+	**/
 	public function drawCircle( cx : Float, cy : Float, radius : Float, nsegments = 0 ) {
 		flush();
 		if( nsegments == 0 )
@@ -531,6 +630,15 @@ class Graphics extends Drawable {
 		flush();
 	}
 
+	/**
+		Draws an ellipse centered at given position.
+		@param cx X center position of the ellipse.
+		@param cy Y center position of the ellipse.
+		@param radiusX Horizontal radius of an ellipse.
+		@param radiusY Vertical radius of an ellipse.
+		@param rotationAngle Ellipse rotation in radians.
+		@param nsegments Amount of segments used to draw an ellipse. When `0`, amount of segments calculated automatically.
+	**/
 	public function drawEllipse( cx : Float, cy : Float, radiusX : Float, radiusY : Float, rotationAngle : Float = 0, nsegments = 0 ) {
 		flush();
 		if( nsegments == 0 )
@@ -547,6 +655,15 @@ class Graphics extends Drawable {
 		flush();
 	}
 
+	/**
+		Draws a pie centered at given position.
+		@param cx X center position of the pie.
+		@param cy Y center position of the pie.
+		@param radius Radius of the pie.
+		@param angleStart Starting angle of the pie in radians.
+		@param angleLength The pie size in clockwise direction with `2*PI` being full circle.
+		@param nsegments Amount of segments used to draw the pie. When `0`, amount of segments calculated automatically.
+	**/
 	public function drawPie( cx : Float, cy : Float, radius : Float, angleStart:Float, angleLength:Float, nsegments = 0 ) {
 		if(Math.abs(angleLength) >= Math.PI * 2) {
 			return drawCircle(cx, cy, radius, nsegments);
@@ -565,6 +682,16 @@ class Graphics extends Drawable {
 		flush();
 	}
 
+	/**
+		Draws a double-edged pie centered at given position.
+		@param cx X center position of the pie.
+		@param cy Y center position of the pie.
+		@param radius The outer radius of the pie.
+		@param innerRadius The inner radius of the pie.
+		@param angleStart Starting angle of the pie in radians.
+		@param angleLength The pie size in clockwise direction with `2*PI` being full circle.
+		@param nsegments Amount of segments used to draw the pie. When `0`, amount of segments calculated automatically.
+	**/
 	public function drawPieInner( cx : Float, cy : Float, radius : Float, innerRadius : Float, angleStart:Float, angleLength:Float, nsegments = 0 ) {
 		flush();
 		if( Math.abs(angleLength) >= Math.PI * 2 + 1e-3 ) angleLength = Math.PI*2+1e-3;
@@ -592,6 +719,16 @@ class Graphics extends Drawable {
 		flush();
 	}
 
+	/**
+		Draws a rectangular pie centered at given position.
+		@param cx X center position of the pie.
+		@param cy Y center position of the pie.
+		@param width Width of the pie.
+		@param height Height of the pie.
+		@param angleStart Starting angle of the pie in radians.
+		@param angleLength The pie size in clockwise direction with `2*PI` being solid rectangle.
+		@param nsegments Amount of segments used to draw the pie. When `0`, amount of segments calculated automatically.
+	**/
 	public function drawRectanglePie( cx : Float, cy : Float, width : Float, height : Float, angleStart:Float, angleLength:Float, nsegments = 0 ) {
 		if(Math.abs(angleLength) >= Math.PI*2) {
 			return drawRect(cx-(width/2), cy-(height/2), width, height);
@@ -664,10 +801,24 @@ class Graphics extends Drawable {
 		lineTo(dx, dy);
 	}
 
+	/**
+		Draws a straight line from the current drawing position to the given position.
+	**/
 	public inline function lineTo( x : Float, y : Float ) {
 		addVertex(x, y, curR, curG, curB, curA, x * ma + y * mc + mx, x * mb + y * md + my);
 	}
 
+	/**
+		Advanced usage. Adds new vertex to the current polygon with given parameters and current line style.
+		@param x Vertex X position
+		@param y Vertex Y position
+		@param r Red tint value of the vertex when performing fill operation.
+		@param g Green tint value of the vertex when performing fill operation.
+		@param b Blue tint value of the vertex when performing fill operation.
+		@param a Alpha of the vertex when performing fill operation.
+		@param u Normalized horizontal Texture position from the current Tile fill operation.
+		@param v Normalized vertical Texture position from the current Tile fill operation.
+	**/
 	public function addVertex( x : Float, y : Float, r : Float, g : Float, b : Float, a : Float, u : Float = 0., v : Float = 0. ) {
 		if( x < xMin ) xMin = x;
 		if( y < yMin ) yMin = y;

+ 39 - 10
h2d/HtmlText.hx

@@ -2,6 +2,9 @@ package h2d;
 
 import h2d.Text;
 
+/**
+	The `HtmlText` line height calculation rules.
+**/
 enum LineHeightMode {
 	/**
 		Accurate line height calculations. Each line will adjust it's height according to it's contents.
@@ -12,17 +15,34 @@ enum LineHeightMode {
 	**/
 	TextOnly;
 	/**
-		Legacy line height mode. When used, line heights are remain constant based on `HtmlText.font` variable.
+		Legacy line height mode. When used, line heights remain constant based on `Text.font` variable.
 	**/
 	Constant;
 }
 
+/**
+	`HtmlText` img tag vertical alignment rules.
+**/
 enum ImageVerticalAlign {
+	/**
+		Align images along the top of the text line.
+	**/
 	Top;
+	/**
+		Align images to sit on the base line of the text.
+	**/
 	Bottom;
+	/**
+		Align images to the middle between the top of the text line its base line.
+	**/
 	Middle;
 }
 
+/**
+	A simple HTML text renderer.
+
+	See the [Text](https://github.com/HeapsIO/heaps/wiki/Text) section of the manual for more details and a list of the supported HTML tags.
+**/
 class HtmlText extends Text {
 
 	/**
@@ -40,26 +60,30 @@ class HtmlText extends Text {
 	}
 
 	/**
-		A default method HtmlText uses to format assigned text.
+		A default method HtmlText uses to format assigned text. See `HtmlText.formatText` for details.
 	**/
 	public static dynamic function defaultFormatText( text : String ) : String {
 		return text;
 	}
 
+	/**
+		When enabled, condenses extra spaces (carriage-return, line-feed, tabulation and space character) to one space.
+		If not set, uncondensed whitespace is left as is, as well as line-breaks.
+	**/
 	public var condenseWhite(default,set) : Bool = true;
 	/**
-		Spacing after <img> tags in pixels.
+		The spacing after `<img>` tags in pixels.
 	**/
 	public var imageSpacing(default,set):Float = 1;
 
 	/**
-		Line height calculation mode controls how much space lines take up vertically. ( default : Accurate )
-		Changing mode to `Constant` restores legacy behavior of HtmlText.
+		Line height calculation mode controls how much space lines take up vertically.
+		Changing mode to `Constant` restores the legacy behavior of HtmlText.
 	**/
 	public var lineHeightMode(default,set) : LineHeightMode = Accurate;
 
 	/**
-		Vertical alignement of the image related to the text
+		Vertical alignment of the images in `<img>` tag relative to the text.
 	**/
 	public var imageVerticalAlign(default,set) : ImageVerticalAlign = Bottom;
 
@@ -100,9 +124,10 @@ class HtmlText extends Text {
 	}
 
 	/**
-		Method that should return `h2d.Tile` instance for `<img>` tags. By default calls `HtmlText.defaultLoadImage` method.
+		Method that should return an `h2d.Tile` instance for `<img>` tags. By default calls `HtmlText.defaultLoadImage` method.
+
 		HtmlText does not cache tile instances.
-		Due to internal structure, method should be determenistic and always return same Tile on consequent calls with same `url` input.
+		Due to internal structure, method should be deterministic and always return same Tile on consequent calls with same `url` input.
 		@param url A value contained in `src` attribute.
 	**/
 	public dynamic function loadImage( url : String ) : Tile {
@@ -110,9 +135,10 @@ class HtmlText extends Text {
 	}
 
 	/**
-		Method that should return `h2d.Font` instance for `<font>` tags with `face` attribute. By default calls `HtmlText.defaultLoadFont` method.
+		Method that should return an `h2d.Font` instance for `<font>` tags with `face` attribute. By default calls `HtmlText.defaultLoadFont` method.
+
 		HtmlText does not cache font instances and it's recommended to perform said caching from outside.
-		Due to internal structure, method should be determenistic and always return same Font instance on consequent calls with same `name` input.
+		Due to internal structure, method should be deterministic and always return same Font instance on consequent calls with same `name` input.
 		@param name A value contained in `face` attribute.
 		@returns Method should return loaded font instance or `null`. If `null` is returned - currently active font is used.
 	**/
@@ -128,6 +154,9 @@ class HtmlText extends Text {
 	public dynamic function onHyperlink(url:String) : Void {
 	}
 
+	/**
+		Called when text is assigned, allowing to process arbitrary text to a valid XHTML.
+	**/
 	public dynamic function formatText( text : String ) : String {
 		return defaultFormatText(text);
 	}

+ 140 - 27
h2d/Interactive.hx

@@ -1,34 +1,54 @@
 package h2d;
 
+/**
+	A user input handler.
+
+	Hitbox area can be a rectangle, an ellipse or an arbitrary shape (`h2d.col.Collider`).
+
+	Note that Interactive does not reports its hitbox bounds in `Object.getBounds`
+	unless `Interactive.backgroundColor` is set, in which case `width` and `height` are reported.
+
+	By default, Interactive only reacts to primary (left) mouse button for actions, see `Interactive.enableRightButton` for details.
+**/
 @:allow(h2d.Scene)
 class Interactive extends Drawable implements hxd.SceneEvents.Interactive {
 
 	/**
-		Width of the Interactive. Ignored if `shape` is set.
+		Width of the Interactive. Ignored if `Interactive.shape` is set.
 	**/
 	public var width : Float;
 	/**
-		Height of the Interactive. Ignored if `shape` is set.
+		Height of the Interactive. Ignored if `Interactive.shape` is set.
 	**/
 	public var height : Float;
 	/**
-		Cursor used when Interactive is under mouse cursor ( default : Button )
+		Cursor used when Interactive is under mouse cursor.
 	**/
-	public var cursor(default,set) : Null<hxd.Cursor>;
+	public var cursor(default,set) : Null<hxd.Cursor> = Button;
 	/**
-		Should object collision be in rectangle or ellipse form? Ignored if `shape` is set.
+		Performs an elliptic hit-test instead of rectangular one based on `Interactive.width` and `height`. Ignored if `Interactive.shape` is set.
 	**/
 	public var isEllipse : Bool;
 	/**
-		Set the default `cancel` mode (see `hxd.Event`), default to false.
+		Set the default `hxd.Event.cancel` mode.
 	**/
 	public var cancelEvents : Bool = false;
 	/**
-		Set the default `propagate` mode (see `hxd.Event`), default to false.
+		Set the default `hxd.Event.propagate` mode.
 	**/
 	public var propagateEvents : Bool = false;
+	/**
+		If set, Interactive will draw a `Tile` with `[width, height]` dimensions of specified color (including alpha).
+	**/
 	public var backgroundColor : Null<Int>;
-	public var enableRightButton : Bool;
+	/**
+		When enabled, interacting with secondary mouse buttons (right button/wheel) will cause `onPush`, `onClick`, `onRelease` and `onReleaseOutside` callbacks.
+		Otherwise those callbacks will only be triggered with primary mouse button (left button).
+
+		Note that Interactive remembers only the last pressed button when pressing on it, hence pressing Interactive with the left button and then the right button
+		would not cause `onClick` on either when releasing left button first, as pressed state is reset internally.
+	**/
+	public var enableRightButton : Bool = false;
 	var scene : Scene;
 	var mouseDownButton : Int = -1;
 	var parentMask : Mask;
@@ -48,12 +68,18 @@ class Interactive extends Drawable implements hxd.SceneEvents.Interactive {
 	**/
 	public var shapeY : Float = 0;
 
-	public function new(width, height, ?parent, ?shape) {
+	/**
+		Create a new Interactive with specified parameters. `width`, `height` and `parent` with optional detailed `shape`.
+		@param width The width of the Interactive hitbox.
+		@param height The height of the Interactive hitbox.
+		@param parent An optional parent `h2d.Object` instance to which Interactive adds itself if set.
+		@param shape An optional detailed Interactive hitbox.
+	**/
+	public function new( width, height, ?parent, ?shape ) {
 		super(parent);
 		this.width = width;
 		this.height = height;
 		this.shape = shape;
-		cursor = Button;
 	}
 
 	override function onAdd() {
@@ -114,16 +140,18 @@ class Interactive extends Drawable implements hxd.SceneEvents.Interactive {
 	}
 
 	/**
-		This can be called during or after a push event in order to prevent the release from triggering a click.
+		Reset current pressed state of the Interactive, preventing the `onClick` or `onReleaseOutside` being triggered when user releases mouse button.
 	**/
 	public function preventClick() {
 		mouseDownButton = -1;
 	}
 
+	@:dox(hide)
 	@:noCompletion public function getInteractiveScene() : hxd.SceneEvents.InteractiveScene {
 		return scene;
 	}
 
+	@:dox(hide)
 	@:noCompletion public function handleEvent( e : hxd.Event ) {
 		if( parentMask != null && checkBounds(e) ) {
 			var p = parentMask;
@@ -219,7 +247,20 @@ class Interactive extends Drawable implements hxd.SceneEvents.Interactive {
 		e.relY = (-dx * i.matB + dy * i.matA) * i.invDet;
 	}
 
-	public function startDrag(callb,?onCancel) {
+	/**
+		Starts input events capture and redirects them to `callb` method until `Interactive.stopDrag` is called.
+		While the method name may imply that only mouse events would be captured: This is not the case,
+		as it will also capture all other input events, including keyboard events.
+
+		Starting event capture through `Interactive.startDrag` will convert `Event.relX` and `relY` to local coordinates
+		of the Interactive and will restore them after invoking `callb`.
+		In order to receive coordinates in scene coordinate space use `Scene.startDrag`.
+
+		@param callb A callback method that receives `hxd.Event` when input event happens.
+		Unless `callb` sets `Event.propagate` to `true`, event won't be sent to other Interactives.
+		@param onCancel An optional callback that is invoked when `Interactive.stopDrag` is called.
+	**/
+	public function startDrag( callb : hxd.Event -> Void,?onCancel : Void -> Void ) {
 		scene.startDrag(function(event) {
 			var x = event.relX, y = event.relY;
 			eventToLocal(event);
@@ -229,92 +270,164 @@ class Interactive extends Drawable implements hxd.SceneEvents.Interactive {
 		},onCancel);
 	}
 
+	/**
+		Stops current input event capture.
+	**/
 	public function stopDrag() {
 		scene.stopDrag();
 	}
 
+	/**
+		Sets focus on this `Interactive`.
+		If Interactive was not already focused and it receives focus - `onFocus` event is sent.
+		Interactive won't become focused if during `onFocus` call it will set `Event.cancel` to `true`.
+	**/
 	public function focus() {
 		if( scene == null || scene.events == null )
 			return;
 		scene.events.focus(this);
 	}
 
+	/**
+		Removes focus from interactive if it's focused.
+		If Interactive is currently focused - `onFocusLost` event will be sent.
+		Interactive won't lose focus if during `onFocusLost` call it will set `Event.cancel` to `true`.
+	**/
 	public function blur() {
 		if( hasFocus() ) scene.events.blur();
 	}
 
+	/**
+		Checks if Interactive is currently hovered by the mouse.
+	**/
 	public function isOver() {
 		return scene != null && scene.events != null && @:privateAccess scene.events.overList.indexOf(this) != -1;
 	}
 
+	/**
+		Checks if Interactive is currently focused.
+	**/
 	public function hasFocus() {
 		return scene != null && scene.events != null && @:privateAccess scene.events.currentFocus == this;
 	}
 
 	/**
 		Sent when mouse enters Interactive hitbox area.
-		`event.propagate` and `event.cancel` are ignored during `onOver`.
+
+		`Event.propagate` and `Event.cancel` are ignored during `onOver`.
 		Propagation can be set with `onMove` event, as well as cancelling `onMove` will prevent `onOver`.
 	**/
 	public dynamic function onOver( e : hxd.Event ) {
 	}
 
-	/** Sent when mouse exits Interactive hitbox area.
-		`event.propagate` and `event.cancel` are ignored during `onOut`.
+	/**
+		Sent when mouse exits Interactive hitbox area.
+		`Event.propagate` and `Event.cancel` are ignored during `onOut`.
 	**/
 	public dynamic function onOut( e : hxd.Event ) {
 	}
 
-	/** Sent when Interactive is pressed by user. **/
+	/**
+		Sent when Interactive is pressed by the user.
+	**/
 	public dynamic function onPush( e : hxd.Event ) {
 	}
 
 	/**
-		Sent on multiple conditions.
-		A. Always sent if user releases mouse while it is inside Interactive hitbox area.
-			This happends regardless if that Interactive was pressed prior or not.
-		B. Sent before `onReleaseOutside` if this Interactive was pressed, but released outside it's bounds.
-		For first case `event.kind` will be `ERelease`, for second case - `EReleaseOutside`.
-		See `onClick` and `onReleaseOutside` functions for separate events that trigger only when user interacts with this particular Interactive.
+		Sent when Interactive is unpressed under multiple circumstances.
+		* Always sent if user releases mouse while it is inside Interactive hitbox area.
+			This happens regardless if that Interactive was pressed prior or not,
+			and due to that it's not guaranteed that `Interactive.onPush` would precede this event.  
+			`Event.kind` is set to `ERelease` during this event.
+		* Sent before `Interactive.onReleaseOutside` if this Interactive was pressed, but released outside its hitbox area.  
+			`Event.kind` is set to `EReleaseOutside` during this event.
+
+		See `Interactive.onClick` and `Interactive.onReleaseOutside` methods for separate events that trigger only when user interacts with this particular Interactive.
 	**/
 	public dynamic function onRelease( e : hxd.Event ) {
 	}
 
 	/**
-		Sent when user presses Interactive, moves mouse outside and releases it.
-		This event fired only on Interactive that user pressed, but released mouse after moving it outside of Interactive hitbox area.
+		Sent when user presses the Interactive, moves the mouse outside its hitbox area and releases the mouse button.
+
+		Can be prevented to fire by calling `Interactive.preventClick` during or after `Interactive.onPush` event.
+
+		`Interactive.onRelease` is sent with `Event.kind` being `EReleaseOutside` just before this event.
 	**/
 	public dynamic function onReleaseOutside( e : hxd.Event ) {
 	}
 
 	/**
-		Sent when Interactive is clicked by user.
-		This event fired only on Interactive that user pressed and released when mouse is inside Interactive hitbox area.
+		Sent when the Interactive is clicked by the user.
+
+		Can be prevented to fire by calling `Interactive.preventClick` during or after `Interactive.onPush` event.
+
+		`Interactive.onRelease` is sent with `Event.kind` being `ERelease` just before this event.
 	**/
 	public dynamic function onClick( e : hxd.Event ) {
 	}
 
+	/**
+		Sent when user moves within the Interactive hitbox area.
+		See `Interactive.onCheck` for event when user does not move the mouse.
+
+		Cancelling the `Event` will prevent interactive from becoming overed,
+		causing `Interactive.onOut` if it was overed previously.
+		Interactive would be treated as not overed as long as event is cancelled even if mouse is within the hitbox area.
+	**/
 	public dynamic function onMove( e : hxd.Event ) {
 	}
-
+	
+	/**
+		Sent when user scrolls mouse wheel above the Interactive. Wheel delta can be obtained through the `Event.wheelDelta`.
+	**/
 	public dynamic function onWheel( e : hxd.Event ) {
 	}
 
+	/**
+		Sent when Interactive receives focus during `Interactive.focus` call.
+
+		Cancelling the `Event` will prevent the Interactive from becoming focused.
+	**/
 	public dynamic function onFocus( e : hxd.Event ) {
 	}
 
+	/**
+		Sent when Interactive lost focus either via `Interactive.blur` call or when user clicks on another Interactive/outside this Interactive hitbox area.
+
+		Cancelling the `Event` will prevent the Interactive from losing focus.
+	**/
 	public dynamic function onFocusLost( e : hxd.Event ) {
 	}
 
+	/**
+		Sent when this Interactive is focused and user unpressed a keyboard key.
+		Unpressed key can be accessed through `Event.keyCode`.
+	**/
 	public dynamic function onKeyUp( e : hxd.Event ) {
 	}
 
+	/**
+		Sent when this Interactive is focused and user pressed a keyboard key.
+		Pressed key can be accessed through `Event.keyCode`.
+	**/
 	public dynamic function onKeyDown( e : hxd.Event ) {
 	}
 
+	/**
+		Sent every frame when user hovers an Interactive but does not move the mouse.
+		See `Interactive.onMove` for event when user moves the mouse.
+
+		Cancelling the `Event` will prevent interactive from becoming overed,
+		causing `Interactive.onOut` if it was overed previously.
+		Interactive would be treated as not overed as long as event is cancelled even if mouse is within the hitbox area.
+	**/
 	public dynamic function onCheck( e : hxd.Event ) {
 	}
 
+	/**
+		Sent when this Interactive is focused and user inputs text. Character added can be accessed through `Event.charCode`.
+	**/
 	public dynamic function onTextInput( e : hxd.Event ) {
 	}
 

+ 47 - 2
h2d/KeyFrames.hx

@@ -1,6 +1,9 @@
 package h2d;
 import hxd.fmt.kframes.Data;
 
+/**
+	[Keyframes](https://github.com/heapsio/keyframes/) integration; A `KeyFrames` animation layer.
+**/
 typedef KeyframesLayer = {
 	var id : Int;
 	var name : String;
@@ -12,7 +15,7 @@ typedef KeyframesLayer = {
 }
 
 /**
-	Adobe After effect player, see https://github.com/heapsio/keyframes/
+	Adobe After effect player, see [Keyframes](https://github.com/heapsio/keyframes/) library.
 **/
 class KeyFrames extends Mask {
 
@@ -20,20 +23,48 @@ class KeyFrames extends Mask {
 	var filePrefix : String;
 	var curFrame : Float;
 
+	/**
+		The FPS provided by the KeyFrames file.
+	**/
 	public var frameRate : Float;
+	/**
+		The total amount of frames in the animation.
+	**/
 	public var frameCount : Int;
+	/**
+		The current playback frame with the frame display progress fraction.
+	**/
 	public var currentFrame(get,set) : Float;
+	/**
+		The playback speed multiplier.
+	**/
 	public var speed : Float = 1.;
+	/**
+		Pauses the playback when enabled.
+	**/
 	public var pause : Bool = false;
+	/**
+		Whether to loop the animation or not.
+	**/
 	public var loop : Bool = false;
 
 	/**
-		When looping, will interpolate between last frame and first frame (default: false)
+		When looping, will interpolate between last frame and first frame.
 	**/
 	public var loopInterpolate : Bool = false;
 
+	/**
+		Use bilinear texture sampling instead of nearest neighbor.
+		@see `Drawable.smooth`
+	**/
 	public var smooth(default,set) = true;
 
+	/**
+		Create a new KeyFrames animation instance.
+		@param file The source file of the animation.
+		@param filePrefix An optional directory prefix when looking up images.
+		@param parent An optional parent `h2d.Object` instance to which KeyFrames adds itself if set.
+	**/
 	public function new( file : KeyframesFile, ?filePrefix : String, ?parent ) {
 		super(0,0,parent);
 		if( file.formatVersion == null )
@@ -95,6 +126,7 @@ class KeyFrames extends Mask {
 		}
 	}
 
+	@:dox(hide) @:noCompletion
 	public function set_smooth( v : Bool ) : Bool {
 		for( l in layers ){
 			var bmp = hxd.impl.Api.downcast(l.spr, h2d.Bitmap);
@@ -104,6 +136,11 @@ class KeyFrames extends Mask {
 		return smooth = v;
 	}
 
+	/**
+		Unpauses the playback and starts it at the specified frame.
+		@param speed The playback speed multiplier at which animation should run.
+		@param startFrame The frame at which the animation should start.
+	**/
 	public function play( speed : Float = 1., startFrame = 0 ) {
 		this.speed = speed;
 		pause = false;
@@ -235,6 +272,9 @@ class KeyFrames extends Mask {
 		return hxd.res.Loader.currentInstance.load(filePrefix == null ? path : filePrefix + path).toTile();
 	}
 
+	/**
+		Returns the animation layer objects under specified name.
+	**/
 	public function getLayer( name : String ) {
 		var layer = null;
 		for( l in layers ) {
@@ -285,6 +325,11 @@ class KeyFrames extends Mask {
 		}
 	}
 
+	/**
+		Sent when animation reaches the end.
+		`KeyFrames.currentFrame` equals to `KeyFrames.frameCount` when `KeyFrames.loop` is disabled,
+		is wrapped around to 0th frame if loop is enabled.
+	**/
 	public dynamic function onAnimEnd() {
 	}
 

+ 42 - 21
h2d/Layers.hx

@@ -1,34 +1,51 @@
 package h2d;
 
 /**
- * `h2d.Layers` allows to hierarchically organize objects on different layers and supports Y-sorting.
- */
+	A layer-based container for Objects.
+
+	Hierarchically organizes objects based on their layer.
+	Supports per-layer Y-sorting through `Layers.ysort`.
+**/
 class Layers extends Object {
 
 	// the per-layer insert position
 	var layersIndexes : Array<Int>;
 	var layerCount : Int;
 
+	/**
+		Create a new Layers instance.
+		@param parent An optional parent `h2d.Object` instance to which Layers adds itself if set.
+	**/
 	public function new(?parent) {
 		super(parent);
 		layersIndexes = [];
 		layerCount = 0;
 	}
 
+	/**
+		Adds a child object `s` at the end of the layer 0.
+		@param s An object to be added.
+	**/
 	override function addChild(s) {
 		addChildAt(s, 0);
 	}
 
 	/**
-	 * Adds a child `h2d.Object` at `layer:Int`. 
-	 * `h2d.Layers.addChildAt` can be used as an alternative.
-	 * @param s `h2d.Object` child to be added.
-	 * @param layer `Int` index of the layer, 0 is the bottom layer.
-	 */
+		Adds a child object `s` at the end of the given `layer`.
+		`h2d.Layers.addChildAt` can be used as an alternative.
+		@param s An object to be added.
+		@param layer An index of the layer, 0 is the bottom-most layer.
+	**/
 	public inline function add(s, layer) {
 		return addChildAt(s, layer);
 	}
 
+	/**
+		Adds a child object `s` at the end of the given `layer`.
+		`h2d.Layers.addChildAt` can be used as an alternative.
+		@param s An object to be added.
+		@param layer An index of the layer, 0 is the bottom-most layer.
+	**/
 	override function addChildAt( s : Object, layer : Int ) {
 		if( s.parent == this ) {
 			var old = s.allocated;
@@ -64,8 +81,9 @@ class Layers extends Object {
 	}
 
 	/**
-	 * Moves an `h2d.Object` to the bottom of its layer (rendered first, behind the other Objects in layer).
-	 * @param s `h2d.Object` to be moved.
+		Moves an object `s` to the bottom of its layer (rendered first, behind the other Objects in the layer).
+		Causes `Object.onHierarchyMoved` on the Object.
+		@param s An object to be moved.
 	 */
 	public function under( s : Object ) {
 		for( i in 0...children.length )
@@ -90,8 +108,9 @@ class Layers extends Object {
 	}
 
 	/**
-	 * Moves an `h2d.Object` to the top of its layer (rendered last, in front of other Objects in layer).
-	 * @param s `h2d.Object` to be moved.
+		Moves an object `s` to the top of its layer (rendered last, in front of other Objects in layer).
+		Causes `Object.onHierarchyMoved` on the Object.
+		@param s An object to be moved.
 	 */
 	public function over( s : Object ) {
 		for( i in 0...children.length )
@@ -111,11 +130,12 @@ class Layers extends Object {
 	}
 
 	/**
-	 * Returns an `Iterator<h2d.Object>` contained in specified layer.  
-	 * Returns empty iterator if layer does not exists.  
-	 * Objects added or removed from Layers during iteration are not added/removed from the `Iterator`.
-	 * @param layer `Int` index of the desired layer.
-	 * @return `Iterator<Object>`
+		Returns an Iterator with objects in a specified `layer`.
+		Returns an empty iterator if no objects are present in the layer.
+
+		Objects added or removed from Layers during iteration do not affect the output of the Iterator.
+
+		@param layer A layer index to iterate over.
 	 */
 	public function getLayer( layer : Int ) : Iterator<Object> {
 		var a;
@@ -130,9 +150,9 @@ class Layers extends Object {
 	}
 
 	/**
-	 * Returns the layer on which the child `h2d.Object` resides.  
-	 * @param s `h2d.Object` 
-	 * @return `Int` index of the layer where `s:h2d.Object` resides or -1 if it's not a child.
+		Returns the layer on which the child `s` resides on.
+		@param s An object to look up to.
+		@return An index of the layer where the object resides on or `-1` if `s` is not a child of the Layers.
 	 */
 	public function getChildLayer( s : Object ) : Int {
 		if ( s.parent != this ) return -1;
@@ -159,8 +179,9 @@ class Layers extends Object {
 	}
 
 	/**
-	 * Sorts specified layer based on Y value of it's children.
-	 * @param layer `Int` index of the layer.
+		Sorts specified layer based on `Object.y` value of it's children.
+		Causes `Object.onHierarchyChanged` on moved children.
+		@param layer An index of the layer to sort.
 	 */
 	public function ysort( layer : Int ) {
 		if( layer >= layerCount ) return;

+ 31 - 6
h2d/Mask.hx

@@ -1,11 +1,24 @@
 package h2d;
 
+/**
+	Restricts rendering area within the `[width, height]` rectangle.
+	For more advanced masking, see `h2d.filter.AbstractMask`.
 
+	Rotation of the mask does not rotate the masked area and instead causes it to cover the bounding box of the mask.
+
+	The `Mask.maskWidth` and `Mask.unmask` can be used to mask out rendering area without direct usage of Mask instance in-between.
+**/
 class Mask extends Object {
 
 	/**
 		Masks render zone based off object position and given dimensions.
 		Should call `Mask.unmask()` afterwards.
+		@param ctx The render context to mask.
+		@param object An Object which transform will be used as mask origin.
+		@param width The width of the mask in scene coordinate space.
+		@param height The height of the mask in scene coordinate space.
+		@param scrollX Additional horizontal offset of the masked area.
+		@param scrollY Additional vertical offset of the masked area.
 	**/
 	@:access(h2d.RenderContext)
 	public static function maskWith( ctx : RenderContext, object : Object, width : Int, height : Int, scrollX : Float = 0, scrollY : Float = 0) {
@@ -34,24 +47,30 @@ class Mask extends Object {
 	}
 
 	/**
-		Unmasks prviously masked area from `Mask.maskWith`.
+		Unmasks the previously masked area from `Mask.maskWith`.
+		@param ctx The render context to unmask.
 	**/
 	public static function unmask( ctx : RenderContext ) {
 		ctx.flush();
 		ctx.popRenderZone();
 	}
 
+	/**
+		The width of the masked area.
+	**/
 	public var width : Int;
+	/**
+		The height of the masked area.
+	**/
 	public var height : Int;
 	var parentMask : Mask;
 
 	/**
-		Horizontal scroll offset of the Mask content in pixels. Can be clamped by `scrollBounds`.
+		Horizontal scroll offset of the Mask content in pixels. Can be clamped by `Mask.scrollBounds`.
 	**/
 	public var scrollX(default, set) : Float = 0;
 	/**
-		Vertical scroll offset of the Mask content in pixels. Can be clamped by `scrollBounds`.
-
+		Vertical scroll offset of the Mask content in pixels. Can be clamped by `Mask.scrollBounds`.
 	**/
 	public var scrollY(default, set) : Float = 0;
 
@@ -60,6 +79,12 @@ class Mask extends Object {
 	**/
 	public var scrollBounds : h2d.col.Bounds;
 
+	/**
+		Create a new Mask instance.
+		@param width The width of the masked area.
+		@param height The height of the masked area.
+		@param parent An optional parent `h2d.Object` instance to which Mask adds itself if set.
+	**/
 	public function new(width, height, ?parent) {
 		super(parent);
 		this.width = width;
@@ -67,7 +92,7 @@ class Mask extends Object {
 	}
 
 	/**
-		Scroll Mask content to specified offset.
+		Scroll the Mask content to the specified offset.
 	**/
 	public function scrollTo( x : Float, y : Float ) {
 		scrollX = x;
@@ -75,7 +100,7 @@ class Mask extends Object {
 	}
 
 	/**
-		Scroll Mask content by specified offset relative to current scroll offset.
+		Scroll the Mask content by the specified offset relative to the current scroll offset.
 	**/
 	public function scrollBy( x : Float, y : Float ) {
 		scrollX += x;

+ 173 - 48
h2d/Object.hx

@@ -2,9 +2,20 @@ package h2d;
 import hxd.Math;
 
 /**
-	h2d.Object is the base 2D class that all scene tree elements inherit from.
-	It can be used to create a virtual container that does not display anything but can contain other objects
+	A base 2D class that all scene tree elements inherit from.
+
+	Serves as a virtual container that does not display anything but can contain other objects
 	so the various transforms are inherited to its children.
+	
+	Private events `Object.onAdd`, `Object.onRemove` and `Object.onHierarchyChanged` can be used
+	to capture when Object is added/removed from the currently active scene as well as being moved withing the object tree.
+
+	Object exposes a number of properties to control position, scale and rotation of the Object relative to its parent,
+	but they are used indirectly during rendering. Instead, they are being used to calculate the absolute matrix transform
+	relative to the Scene. As optimization, it's not recalculated as soon as properties are modified and delayed until
+	`Object.sync`. Absolute object position can be accessed through private variables `Object.matA`, `Object.matB`,
+	`Object.matC`, `Object.matD`, `Object.absX` and `Object.absY`.
+	But it should be noted that in order to ensure up-to-date values, it's advised to call `Object.syncPos` before accessing them.
 **/
 @:allow(h2d.Tools)
 class Object #if (domkit && !domkit_heaps) implements domkit.Model<h2d.Object> #end {
@@ -12,6 +23,11 @@ class Object #if (domkit && !domkit_heaps) implements domkit.Model<h2d.Object> #
 	static var nullDrawable : h2d.Drawable;
 
 	var children : Array<Object>;
+	/**
+		The parent container of this object.
+		See `Object.contentChanged` for more details.
+	**/
+	@:dox(show)
 	var parentContainer : Object;
 
 	/**
@@ -25,61 +41,63 @@ class Object #if (domkit && !domkit_heaps) implements domkit.Model<h2d.Object> #
 	public var numChildren(get, never) : Int;
 
 	/**
-		The name of the object, can be used to retrieve an object within a tree by using `getObjectByName` (default null)
+		The name of the object. Can be used to retrieve an object within a tree by using `Object.getObjectByName`.
 	**/
 	public var name : String;
 
 	/**
 		The x position (in pixels) of the object relative to its parent.
 	**/
-	public var x(default,set) : Float;
+	public var x(default,set) : Float = 0;
 
 	/**
 		The y position (in pixels) of the object relative to its parent.
 	**/
-	public var y(default, set) : Float;
+	public var y(default, set) : Float = 0;
 
 	/**
-		The amount of horizontal scaling of this object (default 1.0)
+		The amount of horizontal scaling of this object.
 	**/
-	public var scaleX(default,set) : Float;
+	public var scaleX(default,set) : Float = 1;
 
 	/**
-		The amount of vertical scaling of this object (default 1.0)
+		The amount of vertical scaling of this object.
 	**/
-	public var scaleY(default,set) : Float;
+	public var scaleY(default,set) : Float = 1;
 
 	/**
 		The rotation angle of this object, in radians.
 	**/
-	public var rotation(default, set) : Float;
+	public var rotation(default, set) : Float = 0;
 
 	/**
-		Is the object and its children are displayed on screen (default true).
+		Is the object and its children are displayed on screen.
 	**/
-	public var visible(default, set) : Bool;
+	public var visible(default, set) : Bool = true;
 
 	/**
-		The amount of transparency of the Object (default 1.0)
+		The amount of transparency of the Object.
 	**/
 	public var alpha : Float = 1.;
 
 	/**
 		The post process filter for this object.
-		When set, `alpha` value affects both filter and object transparency (use `Drawable.color.a` to set transparency only for the object).
+
+		When set, `Object.alpha` value affects both filter and object transparency (use `Drawable.color.a` to set transparency only for the object).
 	**/
 	public var filter(default,set) : h2d.filter.Filter;
 
 	/**
-		The blendMode of the object (default Alpha).
-		If there is no filter active, only apply to the current object (not inherited by children)
-		If there is a filter active, tells how the filter is blended with background.
+		The blending mode of the object.
+
+		If there is no `Object.filter` active, only applies to the current object (not inherited by children).
+		Otherwise tells how the filter is blended with background.
 	**/
-	public var blendMode : BlendMode;
+	public var blendMode : BlendMode = Alpha;
 
 	#if domkit
 	public var dom : domkit.Properties<h2d.Object>;
-	@:noCompletion public inline function getChildren() return children;
+	@:dox(hide) @:noCompletion public inline function getChildren() return children;
 	#end
 
 	var matA : Float;
@@ -89,19 +107,30 @@ class Object #if (domkit && !domkit_heaps) implements domkit.Model<h2d.Object> #
 	var absX : Float;
 	var absY : Float;
 
+	/**
+		A flag that indicates that the object transform was modified and absolute position recalculation is required.
+
+		Automatically cleared on `Object.sync` and can be manually synced with the `Object.syncPos`.
+	**/
+	@:dox(show)
 	var posChanged : Bool;
+	/**
+		A flag that indicates whether the object was allocated or not.
+
+		When adding children to allocated objects, `onAdd` is being called immediately,
+		otherwise it's delayed until the whole tree is added to a currently active `Scene`.
+	**/
+	@:dox(show)
 	var allocated : Bool;
 	var lastFrame : Int;
 
 	/**
-		Create a new empty object, and adds it to the parent object if not null.
+		Create a new empty object.
+		@param parent An optional parent `h2d.Object` instance to which Object adds itself if set.
 	**/
 	public function new( ?parent : Object ) {
 		matA = 1; matB = 0; matC = 0; matD = 1; absX = 0; absY = 0;
-		x = 0; y = 0; scaleX = 1; scaleY = 1; rotation = 0;
-		blendMode = Alpha;
 		posChanged = parent != null;
-		visible = true;
 		children = [];
 		if( parent != null )
 			parent.addChild(this);
@@ -109,9 +138,9 @@ class Object #if (domkit && !domkit_heaps) implements domkit.Model<h2d.Object> #
 
 	/**
 		Return the bounds of the object for its whole content, recursively.
-		If relativeTo is null, it will return the bounds in the absolute coordinates.
-		If not, it will return the bounds relative to the specified object coordinates.
-		You can pass an already allocated bounds or getBounds will allocate one for you and return it.
+		@param relativeTo An optional object relative to coordinates of which bounds are returned.
+		Returns bounds in the absolute coordinates if not set.
+		@param out An optional bounds instance to fill. Allocates new Bounds instance and returns it if not set.
 	**/
 	public function getBounds( ?relativeTo : Object, ?out : h2d.col.Bounds ) : h2d.col.Bounds {
 		if( out == null ) out = new h2d.col.Bounds() else out.empty();
@@ -129,9 +158,10 @@ class Object #if (domkit && !domkit_heaps) implements domkit.Model<h2d.Object> #
 	}
 
 	/**
-		Similar to getBounds(parent), but instead of the full content, it will return
-		the size based on the alignement of the object. For instance for a text, getBounds will return
-		the full glyphs size whereas getSize() will ignore the pixels under the baseline.
+		Similar to `getBounds(parent)`, but instead of the full content, it will return
+		the size based on the alignment of the object. For instance for a text, `Object.getBounds` will return
+		the full glyphs size whereas `getSize` will ignore the pixels under the baseline.
+		@param out An optional bounds instance to fill. Allocates new Bounds instance and returns it if not set.
 	**/
 	public function getSize( ?out : h2d.col.Bounds ) : h2d.col.Bounds {
 		if( out == null ) out = new h2d.col.Bounds() else out.empty();
@@ -148,7 +178,7 @@ class Object #if (domkit && !domkit_heaps) implements domkit.Model<h2d.Object> #
 
 
 	/**
-		Returns the updated absolute position matrix.
+		Returns the updated absolute position matrix. See `Object.getMatrix` for current matrix values.
 	**/
 	public function getAbsPos() {
 		syncPos();
@@ -178,6 +208,7 @@ class Object #if (domkit && !domkit_heaps) implements domkit.Model<h2d.Object> #
 
 	/**
 		Find several objects in the tree by calling `f` on each and returning all the not-null values returned.
+		@param arr An optional array instance to fill results with. Allocates a new array if not set.
 	**/
 	public function findAll<T>( f : Object -> Null<T>, ?arr : Array<T> ) : Array<T> {
 		if( arr == null ) arr = [];
@@ -196,6 +227,14 @@ class Object #if (domkit && !domkit_heaps) implements domkit.Model<h2d.Object> #
 		return f;
 	}
 
+	/**
+		Override this method in order to expand the reported bounds of an object. `Object.addBounds` can be used to add bounds with respect to `relativeTo`.
+		Do not remove the super call.
+		@param relativeTo An object relative to which the Object bounds coordinates should be.
+		@param out An output Bounds instance.
+		@param forSize Whether it's being called for `Object.getSize` or `Object.getBounds`.
+	**/
+	@:dox(show)
 	function getBoundsRec( relativeTo : Object, out : h2d.col.Bounds, forSize : Bool ) : Void {
 		if( posChanged ) {
 			calcAbsPos();
@@ -229,6 +268,16 @@ class Object #if (domkit && !domkit_heaps) implements domkit.Model<h2d.Object> #
 		out.yMax = ymax;
 	}
 
+	/**
+		Adds specified area in local coordinate space to the bounds. Expected to be used within `Object.getBoundsRec`.
+		@param relativeTo An object relative to which the Object bounds coordinates should be. If not set, coordinates are in absolute coordinate space.
+		@param out An output Bounds instance.
+		@param dx The top-left X offset of the added bounds rectangle.
+		@param dy The top-left Y offset of the added bounds rectangle.
+		@param width The width of the added bounds rectangle.
+		@param height The height of the added bounds rectangle.
+	**/
+	@:dox(show)
 	function addBounds( relativeTo : Object, out : h2d.col.Bounds, dx : Float, dy : Float, width : Float, height : Float ) {
 
 		if( width <= 0 || height <= 0 ) return;
@@ -282,7 +331,7 @@ class Object #if (domkit && !domkit_heaps) implements domkit.Model<h2d.Object> #
 	}
 
 	/**
-		Return the total number of children, recursively.
+		Return the total number of children in the whole tree, recursively.
 	**/
 	public function getObjectsCount() : Int {
 		var k = 0;
@@ -292,7 +341,8 @@ class Object #if (domkit && !domkit_heaps) implements domkit.Model<h2d.Object> #
 	}
 
 	/**
-		Convert a local position (or [0,0] if pt is null) relative to the object origin into an absolute screen position, applying all the inherited transforms.
+		Convert a local position (or `[0,0]` if `pt` is null) relative to the object origin into an absolute screen position, applying all the inherited transforms.
+		@param pt An optional position to convert and return. Allocates new Point at 0,0 position if not set. Modifies the Point instance as is.
 	**/
 	public function localToGlobal( ?pt : h2d.col.Point ) : h2d.col.Point {
 		syncPos();
@@ -306,6 +356,7 @@ class Object #if (domkit && !domkit_heaps) implements domkit.Model<h2d.Object> #
 
 	/**
 		Convert an absolute screen position into a local position relative to the object origin, applying all the inherited transforms.
+		@param pt A position to convert and return. Modifies the Point instance as is.
 	**/
 	public function globalToLocal( pt : h2d.col.Point ) : h2d.col.Point {
 		syncPos();
@@ -319,6 +370,9 @@ class Object #if (domkit && !domkit_heaps) implements domkit.Model<h2d.Object> #
 		return pt;
 	}
 
+	/**
+		Returns an `h2d.Scene` down the hierarchy tree or `null` if object is not added to Scene.
+	**/
 	public function getScene() : Scene {
 		var p = this;
 		while( p.parent != null ) p = p.parent;
@@ -377,17 +431,33 @@ class Object #if (domkit && !domkit_heaps) implements domkit.Model<h2d.Object> #
 		#end
 	}
 
+	/**
+		Should be called when Object content was changed in order to notify parent container. See `Object.contentChanged`.
+	**/
+	@:dox(show)
 	inline function onContentChanged() {
 		if( parentContainer != null ) parentContainer.contentChanged(this);
 	}
 
-	// called when we're allocated already but moved in hierarchy
+	/**
+		Sent when object was already allocated and moved within scene object tree hierarchy.
+
+		Do not remove the super call when overriding.
+
+		@param parentChanged Whether Object was moved withing same parent (through `Layers.ysort` for example) or relocated to a new one.
+	**/
+	@:dox(show)
 	function onHierarchyMoved( parentChanged : Bool ) {
 		for ( c in children )
 			c.onHierarchyMoved(parentChanged);
 	}
 
-	// kept for internal init
+	/**
+		Sent when object is being added to an allocated scene.
+
+		Do not remove the super call when overriding.
+	**/
+	@:dox(show)
 	function onAdd() {
 		allocated = true;
 		if( filter != null )
@@ -396,7 +466,13 @@ class Object #if (domkit && !domkit_heaps) implements domkit.Model<h2d.Object> #
 			c.onAdd();
 	}
 
-	// kept for internal cleanup
+
+	/**
+		Sent when object is removed from the allocated scene.
+
+		Do not remove the super call when overriding.
+	**/
+	@:dox(show)
 	function onRemove() {
 		allocated = false;
 		if( filter != null )
@@ -405,6 +481,10 @@ class Object #if (domkit && !domkit_heaps) implements domkit.Model<h2d.Object> #
 			c.onRemove();
 	}
 
+	/**
+		Populates Matrix with current absolute object transform values. See `Object.getAbsPos` for up-to-date values.
+	**/
+	@:dox(show)
 	function getMatrix( m : h2d.col.Matrix ) {
 		m.a = matA;
 		m.b = matB;
@@ -415,7 +495,7 @@ class Object #if (domkit && !domkit_heaps) implements domkit.Model<h2d.Object> #
 	}
 
 	/**
-		Remove the given object from our immediate children list if it's part of it.
+		Remove the given object from the immediate children list of the object if it's part of it.
 	**/
 	public function removeChild( s : Object ) {
 		if( children.remove(s) ) {
@@ -430,6 +510,11 @@ class Object #if (domkit && !domkit_heaps) implements domkit.Model<h2d.Object> #
 		}
 	}
 
+	/**
+		Sets the parent container for this Object and it's children. 
+		See `Object.contentChanged` for more details.
+	**/
+	@:dox(show)
 	function setParentContainer( c : Object ) {
 		parentContainer = c;
 		for( s in children )
@@ -437,7 +522,7 @@ class Object #if (domkit && !domkit_heaps) implements domkit.Model<h2d.Object> #
 	}
 
 	/**
-		Remove all children from our immediate children list
+		Remove all children from the immediate children list.
 	**/
 	public function removeChildren() {
 		while( numChildren>0 )
@@ -445,15 +530,14 @@ class Object #if (domkit && !domkit_heaps) implements domkit.Model<h2d.Object> #
 	}
 
 	/**
-		Same as parent.removeChild(this), but does nothing if parent is null.
-		In order to capture add/removal from scene, you can override onAdd/onRemove/onHierarchyMoved
+		Same as `parent.removeChild(this)`, but does nothing if parent is null.
 	**/
 	public inline function remove() {
 		if( this != null && parent != null ) parent.removeChild(this);
 	}
 
 	/**
-		Draw the object and all its children into the given Texture
+		Draw the object and all its children into the given Texture.
 	**/
 	public function drawTo( t : h3d.mat.Texture ) {
 		var s = getScene();
@@ -467,7 +551,7 @@ class Object #if (domkit && !domkit_heaps) implements domkit.Model<h2d.Object> #
 	}
 
 	/**
-		Draw the object and all its children into the given Textures
+		Draw the object and all its children into the given Textures.
 	**/
 	public function drawToTextures( texs : Array<h3d.mat.Texture>, outputs : Array<hxsl.Output> ) {
 		var s = getScene();
@@ -480,9 +564,21 @@ class Object #if (domkit && !domkit_heaps) implements domkit.Model<h2d.Object> #
 		}
 	}
 
+	/**
+		Override this method in order to add custom graphics rendering to your Object.
+		`draw` is invoked before rendering of the object children.
+	**/
+	@:dox(show)
 	function draw( ctx : RenderContext ) {
 	}
 
+	/**
+		Performs a sync of data for rendering (such as absolute position recalculation).
+		While this method can be used as a substitute to an update loop, it's primary purpose it to prepare the Object to be rendered.
+
+		Do not remove the super call when overriding.
+	**/
+	@:dox(show)
 	function sync( ctx : RenderContext ) {
 		var changed = posChanged;
 		if( changed ) {
@@ -510,6 +606,10 @@ class Object #if (domkit && !domkit_heaps) implements domkit.Model<h2d.Object> #
 		}
 	}
 
+	/**
+		Ensures that object has an up-to-date position transform.
+	**/
+	@:dox(show)
 	function syncPos() {
 		if( parent != null ) parent.syncPos();
 		if( posChanged ) {
@@ -520,6 +620,13 @@ class Object #if (domkit && !domkit_heaps) implements domkit.Model<h2d.Object> #
 		}
 	}
 
+	/**
+		<span class="label">Internal usage</span>
+		Calculates the absolute object position transform.
+		See `Object.syncPos` for a safe position sync method.
+		This method does not ensure that object parents also have up-to-date transform nor does it clear the `Object.posChanged` flag.
+	**/
+	@:dox(show)
 	function calcAbsPos() {
 		if( parent == null ) {
 			var cr, sr;
@@ -564,6 +671,10 @@ class Object #if (domkit && !domkit_heaps) implements domkit.Model<h2d.Object> #
 		}
 	}
 
+	/**
+		Draws single Tile instance with this Object transform.
+	**/
+	@:dox(show)
 	function emitTile( ctx : RenderContext, tile : h2d.Tile ) {
 		if( nullDrawable == null )
 			nullDrawable = @:privateAccess new h2d.Drawable(null);
@@ -635,8 +746,11 @@ class Object #if (domkit && !domkit_heaps) implements domkit.Model<h2d.Object> #
 	}
 
 	/**
-		Clip a local bounds with our global viewport
+		<span class="label">Internal usage</span>
+		Clip a local bounds with our global viewport.
+		Used during filter rendering in order to clip out areas that are off-screen and should not be rendered.
 	**/
+	@:dox(show)
 	function clipBounds( ctx : RenderContext, bounds : h2d.col.Bounds ) {
 		var view = ctx.tmpBounds;
 		var matA, matB, matC, matD, absX, absY;
@@ -860,7 +974,7 @@ class Object #if (domkit && !domkit_heaps) implements domkit.Model<h2d.Object> #
 	}
 
 	/**
-		Move the object by the specied amount along its current direction (rotation angle).
+		Move the object by the specified amount along its current direction (`Object.rotation` angle).
 	**/
 	public function move( dx : Float, dy : Float ) {
 		x += dx * Math.cos(rotation);
@@ -899,14 +1013,14 @@ class Object #if (domkit && !domkit_heaps) implements domkit.Model<h2d.Object> #
 	}
 
 	/**
-		Return the `n`th element among our immediate children list, or null if there is no.
+		Return the `n`th element among the immediate children list of this object, or `null` if there is no Object at this position.
 	**/
 	public inline function getChildAt( n ) {
 		return children[n];
 	}
 
 	/**
-		Return the index of the object `o` within our immediate children list, or `-1` if it is not part of our children list.
+		Return the index of the object `o` within the immediate children list of this object, or `-1` if it is not part of the children list.
 	**/
 	public function getChildIndex( o ) {
 		for( i in 0...children.length )
@@ -916,7 +1030,7 @@ class Object #if (domkit && !domkit_heaps) implements domkit.Model<h2d.Object> #
 	}
 
 	/**
-		Search for an object recursively by name, return null if not found.
+		Search for an object recursively by name, return `null` if not found.
 	**/
 	public function getObjectByName( name : String ) {
 		if( this.name == name )
@@ -939,6 +1053,7 @@ class Object #if (domkit && !domkit_heaps) implements domkit.Model<h2d.Object> #
 		return new hxd.impl.ArrayIterator(children);
 	}
 
+	@:dox(hide)
 	function toString() {
 		var c = Type.getClassName(Type.getClass(this));
 		return name == null ? c : name + "(" + c + ")";
@@ -947,15 +1062,25 @@ class Object #if (domkit && !domkit_heaps) implements domkit.Model<h2d.Object> #
 	// ---- additional methods for containers (h2d.Flow)
 
 	/**
-		This is called by our children if we have defined their parentContainer when they get resized
+		<span class="label">Advanced usage</span>  
+		Called by the children of a container object if they have `parentContainer` defined in them.
+		Primary use-case is when the child size got changed, requiring content to reevaluate positioning such as `Flow` layouts,
+		but also can be used for other purposes. 
 	**/
+	@:dox(show)
 	function contentChanged( s : Object ) {
 	}
 
 	/**
+		<span class="label">Advanced usage</span>  
 		This can be called by a parent container to constraint the size of its children.
-		Negative value mean that constraint is to be disable.
+		Negative value mean that constraint is to be disabled.
+
+		For example, `Text` constraints it's maximum width, causing word-wrap to occur within constrained area.
+
+		@see `FlowProperties.constraint`
 	**/
+	@:dox(show)
 	function constraintSize( maxWidth : Float, maxHeight : Float ) {
 	}
 

+ 30 - 1
h2d/ObjectFollower.hx

@@ -1,21 +1,50 @@
 package h2d;
 
 /**
-	Allows a 2D object position to follow a 3D object using the current camera.
+	Follows the 3D object position in current 3D camera, synchronizing the follower position to projected 2D position of the followed object.
 **/
 @:uiNoComponent
 class ObjectFollower extends Object {
 
+	/**
+		Reference to target 3D object to follow.
+	**/
 	public var follow : h3d.scene.Object;
+	/**
+		Rounds the resulting 2d position of follower aligning it to s2d pixel grid.
+	**/
 	public var pixelSnap = true;
+	/**
+		If enabled, follower will mirror visibility of target object.
+	**/
 	public var followVisibility = false;
+	/**
+		Extra camera projection offset along X-axis to which follower will attach to.
+	**/
 	public var offsetX = 0.;
+	/**
+		Extra camera projection offset along Y-axis to which follower will attach to.
+	**/
 	public var offsetY = 0.;
+	/**
+		Extra camera projection offset along Z-axis to which follower will attach to.
+	**/
 	public var offsetZ = 0.;
 
+	/**
+		Horizontal object alignment relative to anchoring point.
+	**/
 	public var horizontalAlign : h2d.Flow.FlowAlign = Left;
+	/**
+		Vertical object alignment relative to anchoring point.
+	**/
 	public var verticalAlign : h2d.Flow.FlowAlign = Top;
 
+	/**
+		Create a new ObjectFollower instance.
+		@param obj The 3D object to follow.
+		@param parent An optional parent `h2d.Object` instance to which ObjectFollower adds itself if set.
+	**/
 	public function new( obj, ?parent ) {
 		super(parent);
 		this.follow = obj;

+ 226 - 12
h2d/Particles.hx

@@ -1,5 +1,9 @@
 package h2d;
 
+/**
+	See `ParticleGroup.sortMode` - not used anywhere.
+**/
+@:dox(hide)
 enum PartSortMode {
 	/**
 		Particles are not sorted.
@@ -11,21 +15,24 @@ enum PartSortMode {
 	Dynamic;
 }
 
+/**
+	The particle emission pattern modes. See `ParticleGroup.emitMode`.
+**/
 enum PartEmitMode {
 	/**
-		A single Point, emit in all directions
+		A single Point, that emits in all directions.
 	**/
 	Point;
 	/**
-		A cone, parametrized with emitAngle and emitDistance
+		A cone, parametrized with `emitAngle` and `emitDistance`.
 	**/
 	Cone;
 	/**
-		A box, parametrized with emitDist and emitDistY
+		A box, parametrized with `emitDist` and `emitDistY`.
 	**/
 	Box;
 	/**
-		A box, parametrized with emitAngle and emitDistance
+		A box, parametrized with `emitAngle` and `emitDistance`.
 	**/
 	Direction;
 }
@@ -129,6 +136,9 @@ private class Particle extends h2d.SpriteBatch.BatchElement {
 
 }
 
+/**
+	An emitter of a single particle group. Part of `Particles` simulation system.
+**/
 @:access(h2d.SpriteBatch)
 @:access(h2d.Object)
 class ParticleGroup {
@@ -152,68 +162,211 @@ class ParticleGroup {
 	var needRebuild = true;
 	var tiles : Array<h2d.Tile>;
 
+	/**
+		The group name.
+	**/
 	public var name : String;
+	/**
+		Disabling the group immediately removes it from rendering and resets it's state.
+	**/
 	public var enable(default, set) : Bool = true;
+	/**
+		Does nothing.
+	**/
 	public var sortMode(default, set) : PartSortMode = None;
+	/**
+		Configures blending mode for this group.
+	**/
 	public var blendMode(default, set) : BlendMode = Alpha;
 
+	/**
+		Maximum number of particles alive at a time.
+	**/
 	public var nparts(default, set) : Int 		= 100;
+	/**
+		Initial particle X offset.
+	**/
 	public var dx(default, set) : Int 			= 0;
+	/**
+		Initial particle Y offset.
+	**/
 	public var dy(default, set) : Int 			= 0;
 
+	/**
+		If enabled, group will emit new particles indefinitely maintaining number of particles at `ParticleGroup.nparts`.
+	**/
 	public var emitLoop(default, set) : Bool 	= true;
+	/**
+		The pattern in which particles are emitted. See individual `PartEmitMode` values for more details.
+	**/
 	public var emitMode(default, set):PartEmitMode = Point;
+	/**
+		Initial particle position distance from emission point.
+	**/
 	public var emitStartDist(default, set) : Float = 0.;
+	/**
+		Additional random particle position distance from emission point.
+	**/
 	public var emitDist(default, set) : Float	= 50.;
+	/**
+		Secondary random position distance modifier (used by `Box` emitMode)
+	**/
 	public var emitDistY(default, set) : Float	= 50.;
+	/**
+		Normalized particle emission direction angle.
+	**/
 	public var emitAngle(default, set) : Float 	= -0.5;
+	/**
+		When enabled, particle rotation will match the particle movement direction angle.
+	**/
 	public var emitDirectionAsAngle(default, set) : Bool = false;
+	/**
+		Randomized synchronization delay before particle appears after being emitted.
+
+		Usage note for non-relative mode: Particle will use configuration that was happened at time of emission, not when delay timer runs out.
+	**/
 	public var emitSync(default, set) : Float	= 0;
+	/**
+		Fixed delay before particle appears after being emitted.
+
+		Usage note for non-relative mode: Particle will use configuration that was happened at time of emission, not when delay timer runs out.
+	**/
 	public var emitDelay(default, set) : Float	= 0;
 
+	/**
+		Initial particle size.
+	**/
 	public var size(default, set) : Float		= 1;
+	/**
+		If set, particle will change it's size with time.
+	**/
 	public var sizeIncr(default, set) : Float	= 0;
+	/**
+		If enabled, particle will increase on X-axis with `sizeIncr`.
+	**/
 	public var incrX(default, set) : Bool		= true;
+	/**
+		If enabled, particle will increase on Y-axis with `sizeIncr`.
+	**/
 	public var incrY(default, set) : Bool		= true;
+	/**
+		Additional random size increase when particle is created.
+	**/
 	public var sizeRand(default, set) : Float	= 0;
 
+	/**
+		Initial particle lifetime.
+	**/
 	public var life(default, set) : Float		= 1;
+	/**
+		Additional random lifetime increase when particle is created.
+	**/
 	public var lifeRand(default, set) : Float	= 0;
 
+	/**
+		Initial particle velocity.
+	**/
 	public var speed(default, set) : Float			= 50.;
+	/**
+		Additional random velocity increase when particle is created.
+	**/
 	public var speedRand(default, set) : Float		= 0;
+	/**
+		If set, particle velocity will change over time.
+	**/
 	public var speedIncr(default, set) : Float		= 0;
+	/**
+		Gravity applied to the particle.
+	**/
 	public var gravity(default, set) : Float		= 0;
+	/**
+		The gravity angle in radians. `0` points down.
+	**/
 	public var gravityAngle(default, set) : Float 	= 0;
-	public var cosGravityAngle : Float;
-	public var sinGravityAngle : Float;
+	@:noCompletion @:dox(hide) public var cosGravityAngle : Float;
+	@:noCompletion @:dox(hide) public var sinGravityAngle : Float;
 
+	/**
+		Initial particle rotation.
+	**/
 	public var rotInit(default, set) : Float	= 0;
+	/**
+		Initial rotation speed of the particle.
+	**/
 	public var rotSpeed(default, set) : Float	= 0;
+	/**
+		Additional random rotation speed when particle is created.
+	**/
 	public var rotSpeedRand(default, set):Float = 0;
+	/**
+		If enabled, particles will be automatically rotated in the direction of particle velocity.
+	**/
 	public var rotAuto							= false;
 
+	/**
+		The time in seconds during which particle alpha fades in after being emitted.
+	**/
 	public var fadeIn : Float					= 0.2;
+	/**
+		The time in seconds at which particle will start to fade out before dying. Fade out time can be calculated with `lifetime - fadeOut`.
+	**/
 	public var fadeOut : Float					= 0.8;
+	/**
+		The exponent of the alpha transition speed on fade in and fade out.
+	**/
 	public var fadePower : Float				= 1;
 
+	/**
+		Total count of frames used by the group.
+
+		When 0, amount of frames in a group calculated by `frameDivisionX * frameDivisionY`.
+
+		Otherwise it's `min(frameDivisionX * frameDivisionY, frameCount)`.
+	**/
 	public var frameCount(default,set) : Int		= 0;
+	/**
+		Horizontal frame divisor.
+	**/
 	public var frameDivisionX(default,set) : Int	= 1;
+	/**
+		Vertical frame divisor.
+	**/
 	public var frameDivisionY(default,set) : Int	= 1;
+	/**
+		The amount of times the animations will loop during lifetime.
+		Settings it to 0 will stop the animation playback and each particle will have a random frame assigned at emission time.
+	**/
 	public var animationRepeat(default,set) : Float	= 1;
+	/**
+		The texture used to render particles.
+	**/
 	public var texture(default,set) : h3d.mat.Texture;
+	/**
+		Optional color gradient texture for tinting.
+	**/
 	public var colorGradient(default,set) : h3d.mat.Texture;
 	
-	/** Should partcles follow the emitter or stay in place? **/
+	/**
+		When enabled, causes particles to always render relative to the emitter position, moving along with it.
+		Otherwise, once emitted, particles won't follow the emitter, and will render relative to the scene origin.
+
+		Non-relative mode is useful for simulating something like a smoke coming from a moving object,
+		while relative mode things like jet flame that have to stick to its emission source.
+	**/
 	public var isRelative(default, set) : Bool = true;
-	/** Should group rebuild on parameters change.
-		Note that some parameters take immediate effect on the existing particles, and some would force rebuild reagrdless.
+	/**
+		Should group rebuild on parameters change.
+
+		Note that some parameters take immediate effect on the existing particles, and some would force rebuild regardless of this setting.
+
 		Parameters that take immediate effect:
-		speedIncr, gravity, gravityAngle, fadeIn, fadeOut, fadePower, rotAuto, rotInit, incrX, incrY, emitLoop, blendMode
+		`speedIncr`, `gravity`, `gravityAngle`, `fadeIn`, `fadeOut`, `fadePower`, `rotAuto`, `rotInit`, `incrX`, `incrY`, `emitLoop` and `blendMode`
+
 		Parameters that will always force rebuild:
-		enable, sortMode, isRelative, texture, frameCount, frameDivisionX, frameDivisionY, nparts
+		`enable`, `sortMode`, `isRelative`, `texture`, `frameCount`, `frameDivisionX`, `frameDivisionY` and `nparts`
+
 		Parameters that newer cause rebuild:
-		blendMode, colorGradient, animationRepeat
+		`blendMode`, `colorGradient` and `animationRepeat`
 	**/
 	public var rebuildOnChange : Bool = true;
 
@@ -261,6 +414,10 @@ class ParticleGroup {
 	inline function set_animationRepeat(v) return animationRepeat = v;
 	inline function set_isRelative(v) { needRebuild = true; return isRelative = v; }
 	
+	/**
+		Create a new particle group instance.
+		@param p The parent Particles instance. Group does not automatically adds itself to the Particles.
+	**/
 	public function new(p) {
 		this.parts = p;
 		batch = new SpriteBatch(null, p);
@@ -291,6 +448,9 @@ class ParticleGroup {
 		needRebuild = true;
 	}
 
+	/**
+		Reset current state of particle group and re-emit all particles.
+	**/
 	public function rebuild() {
 		needRebuild = false;
 		batch.clear();
@@ -410,6 +570,9 @@ class ParticleGroup {
 
 	}
 
+	/**
+		Saves the particle group configuration into a `Dynamic` object.
+	**/
 	public function save() {
 		var o : Dynamic = {};
 		for( f in getFields(this) )
@@ -422,6 +585,12 @@ class ParticleGroup {
 		return o;
 	}
 
+	/**
+		Loads the particle group configuration from a given object.
+
+		@param version The version of Particles that were used to save the configuration.
+		@param o The previously saved configuration data to load.
+	**/
 	public function load( version : Int, o : Dynamic ) {
 		for( f in getFields(this) )
 			if( Reflect.hasField(o,f) )
@@ -435,6 +604,18 @@ class ParticleGroup {
 
 }
 
+/**
+	A 2D particle system with wide range of customizability.
+
+	The Particles instance can contain multiple `ParticleGroup` instances - each of which works independently from one another.
+
+	To simplify designing of the particles [HIDE](https://github.com/HeapsIO/hide/) contains a dedicated 2D particle editor and
+	stores the particle data in a JSON format, which then can be loaded with the `Particles.load` method:
+	```haxe
+	var part = new h2d.Particles();
+	part.load(haxe.Json.parse(hxd.Res.my_parts_file.entry.getText()), hxd.Res.my_parts_file.entry.path);
+	```
+**/
 @:access(h2d.ParticleGroup)
 class Particles extends Drawable {
 
@@ -445,6 +626,10 @@ class Particles extends Drawable {
 	var hideProps : Dynamic;
 	var pshader : ParticleShader;
 
+	/**
+		Create a new Particles instance.
+		@param parent An optional parent `h2d.Object` instance to which Particles adds itself if set.
+	**/
 	public function new( ?parent ) {
 		super(parent);
 		groups = [];
@@ -456,17 +641,29 @@ class Particles extends Drawable {
 		return hxd.res.Loader.currentInstance.load(path).toTexture();
 	}
 
+	/**
+		Sent when all particle groups stopped playback.
+		Restarts all groups by default.
+	**/
 	public dynamic function onEnd() {
 		for( g in groups )
 			g.needRebuild = true;
 	}
 
+	/**
+		Saves Particles settings and returns an object that can be saved into a file and then loaded with a `Particles.load` method.
+	**/
 	public function save() : Dynamic {
 		var obj : Dynamic = { type : "particles2D", version : VERSION, groups : [for( g in groups ) g.save()] };
 		if( hideProps != null ) obj.hide = hideProps;
 		return obj;
 	}
 
+	/**
+		Loads previously saved Particles settings.
+		@param o The saved Particles settings.
+		@param resourcePath An optional path of the configuration file. May be safely omitted.
+	**/
 	public function load( o : Dynamic, ?resourcePath : String ) {
 		this.resourcePath = resourcePath;
 		if( o.version == 0 || o.version > VERSION ) throw "Unsupported version " + o.version;
@@ -475,6 +672,14 @@ class Particles extends Drawable {
 		hideProps = o.hide;
 	}
 
+	/**
+		Add new particle group to the Particles.
+		@param g Particle group to add. If null, will create an empty ParticleGroup.
+		Note that when passing existing group, it should be created with this Particles instanceas the constructor argument,
+		otherwise it may lead to undefined behavior.
+		@param index Optional insertion index at which the group should be inserted.
+		@returns Added ParticleGroup instance.
+	**/
 	public function addGroup( ?g : ParticleGroup, ?index ) {
 		if( g == null )
 			g = new ParticleGroup(this);
@@ -486,12 +691,18 @@ class Particles extends Drawable {
 		return g;
 	}
 
+	/**
+		Removes the group from the Particles.
+	**/
 	public function removeGroup( g : ParticleGroup ) {
 		var idx = groups.indexOf(g);
 		if( idx < 0 ) return;
 		groups.splice(idx,1);
 	}
 
+	/**
+		Returns a group with a specified name or `null` if none found.
+	**/
 	public function getGroup( name : String ) {
 		for( g in groups )
 			if( g.name == name )
@@ -548,6 +759,9 @@ class Particles extends Drawable {
 		blendMode = old;
 	}
 
+	/**
+		Returns an Iterator of particle groups within Particles.
+	**/
 	public inline function getGroups() {
 		return groups.iterator();
 	}

+ 159 - 7
h2d/RenderContext.hx

@@ -9,23 +9,73 @@ private typedef TargetStackEntry = CameraStackEntry & {
 
 private typedef RenderZoneStack = { hasRZ:Bool, x:Float, y:Float, w:Float, h:Float };
 
+/**
+	A 2D scene renderer.
+	
+	Passed during `Object.sync` and `Object.drawRec` and can be accessed directly via `Scene.renderer`.
+**/
 @:access(h2d.Scene)
 class RenderContext extends h3d.impl.RenderContext {
 
 	static inline var BUFFERING = #if heaps_emit_tile_buffering true #else false #end;
 
+	/**
+		Current transparency value used for rendering objects. 
+		Automatically managed by `Object`.
+	**/
 	public var globalAlpha = 1.;
+	/**
+		Temporary vertex buffer used to emit Tiles when `RenderContext.BUFFERING` is on.  
+		Otherwise it's `null`. Internal usage only.
+	**/
+	@:dox(hide)
 	public var buffer : hxd.FloatBuffer;
+	/**
+		Current temporary buffer position. Internal usage only.
+	**/
+	@:dox(hide)
 	public var bufPos : Int;
+	/**
+		The 2D scene attached to this RenderContext instance.
+	**/
 	public var scene : h2d.Scene;
+	/**
+		<span class="label">Internal usage</span>
+
+		Determines texture filtering method (Linear or Nearest).
+		Not recommended to use - assign `Scene.defaultSmooth` instead.
+	**/
 	public var defaultSmooth : Bool = false;
+	/**
+		When enabled, pixels with alpha value below 0.001 will be discarded.
+	**/
 	public var killAlpha : Bool;
+	/**
+		When enabled, causes `Object` to render its children in reverse order.
+	**/
 	public var front2back : Bool;
 
-	public var onBeginDraw : h2d.Drawable->Bool; // return false to cancel drawing
+	/**
+		Sent before Drawable is rendered.
+		Drawable won't be rendered if callback returns `false`.
+	**/
+	public var onBeginDraw : h2d.Drawable->Bool;
+	/**
+		Sent before filter begins rendering.
+		Filter (and it's object tree) won't be rendered if callback returns `false`.
+	**/
 	public var onEnterFilter : h2d.Object->Bool;
+	/**
+		Send after filter has been rendered.
+	**/
 	public var onLeaveFilter : h2d.Object->Void;
 
+	/**
+		<span class="label">Internal usage</span>
+		
+		Used to calculate filter rendering bounds.
+	**/
+	@:dox(hide)
 	public var tmpBounds = new h2d.col.Bounds();
 	var texture : h3d.mat.Texture;
 	var baseShader : h3d.shader.Base2d;
@@ -66,6 +116,10 @@ class RenderContext extends h3d.impl.RenderContext {
 	var baseFlipY : Float;
 	var targetFlipY : Float;
 
+	/**
+		Create a new RenderContext and attach it to specified Scene.
+		@param scene The scene which RenderContext will render.
+	**/
 	public function new(scene) {
 		super();
 		this.scene = scene;
@@ -92,10 +146,19 @@ class RenderContext extends h3d.impl.RenderContext {
 		if( fixedBuffer != null ) fixedBuffer.dispose();
 	}
 
+	/**
+		Tells if tile buffering is enabled.
+	**/
+	@:dox(hide)
 	public inline function hasBuffering() {
 		return BUFFERING;
 	}
 
+	/**
+		<span class="label">Internal usage</span>
+		
+		Prepares RenderContext to begin rendering a new frame.
+	**/
 	public function begin() {
 		texture = null;
 		currentObj = null;
@@ -126,12 +189,19 @@ class RenderContext extends h3d.impl.RenderContext {
 		textures.begin();
 	}
 
+	/**
+		Allocated a cached render target Texture with specified name, filter mode and current `Scene.width` and `Scene.height`.
+		@returns Either precached Texture under same name or newly allocated one.
+	**/
 	public function allocTarget(name, filter = false) {
 		var t = textures.allocTarget(name, scene.width, scene.height, false);
 		t.filter = filter ? Linear : Nearest;
 		return t;
 	}
 
+	/**
+		Clears current render target with specified color.
+	**/
 	public function clear(color) {
 		engine.clear(color);
 	}
@@ -148,6 +218,11 @@ class RenderContext extends h3d.impl.RenderContext {
 		engine.uploadShaderBuffers(buffers, Globals);
 	}
 
+	/**
+		<span class="label">Internal usage</span>
+
+		Performers cleanup after frame is rendered.
+	**/
 	public function end() {
 		flush();
 		texture = null;
@@ -157,6 +232,12 @@ class RenderContext extends h3d.impl.RenderContext {
 		if ( cameraStackIndex != 0 ) throw "Missing popCamera()";
 	}
 
+	/**
+		<span class="label">Internal usage</span>
+
+		Applies Camera `cam` transform to current viewport and pushes it onto the camera stack.
+		Should call `RenderContext.popCamera` when rendering is complete.
+	**/
 	@:access(h2d.Camera)
 	public function pushCamera( cam : h2d.Camera ) {
 		var entry = cameraStack[cameraStackIndex++];
@@ -187,6 +268,11 @@ class RenderContext extends h3d.impl.RenderContext {
 		baseShader.viewportB.set(viewB * flipY, viewD * flipY, viewY * flipY);
 	}
 
+	/**
+		<span class="label">Internal usage</span>
+
+		Restores previous viewport state prior to camera rendering, removing it from the camera stack.
+	**/
 	public function popCamera() {
 		if (cameraStackIndex == 0) throw "Too many popCamera()";
 		var inf = cameraStack[--cameraStackIndex];
@@ -201,6 +287,13 @@ class RenderContext extends h3d.impl.RenderContext {
 		baseShader.viewportB.set(viewB * flipY, viewD * flipY, viewY * flipY);
 	}
 
+	/**
+		<span class="label">Internal usage</span>
+
+		Prepares to render Filter and pushes provided Object onto filter stack.
+
+		@returns true if filter is allowed to render, false otherwise (see `RenderContext.onEnterFilter`)
+	**/
 	public function pushFilter( spr : h2d.Object ) {
 		if( filterStack.length == 0 && onEnterFilter != null )
 			if( !onEnterFilter(spr) ) return false;
@@ -209,6 +302,11 @@ class RenderContext extends h3d.impl.RenderContext {
 		return true;
 	}
 
+	/**
+		<span class="label">Internal usage</span>
+
+		Finalizes Filter rendering and removes top-most Object from filter stack.
+	**/
 	public function popFilter() {
 		var spr = filterStack.pop();
 		if( filterStack.length > 0 ) {
@@ -219,6 +317,16 @@ class RenderContext extends h3d.impl.RenderContext {
 		}
 	}
 
+	/**
+		Sets provided texture as a render target and pushes it onto target stack.
+		If only part of the Texture should be rendered onto, method should be used with `pushRenderZone()` to avoid rendering outside specified texture area.
+
+		@param t Texture to which RenderContext will render to. Texture should be allocated as a render target (have `Target` flag).
+		@param startX X offset of rendering area on the Texture.
+		@param startY Y offset of rendering area on the Texture.
+		@param width Width of the clipping area on the Texture. If equals to `-1`, will use texture width.
+		@param height Height of the clipping area on the Texture. If equals to `-1` will use texture height.
+	**/
 	public function pushTarget( t : h3d.mat.Texture, startX = 0, startY = 0, width = -1, height = -1 ) {
 		flush();
 		engine.pushTarget(t);
@@ -260,6 +368,9 @@ class RenderContext extends h3d.impl.RenderContext {
 		if( hasRenderZone ) clearRZ();
 	}
 
+	/**
+		Pushes an array of render targets onto target stack.
+	**/
 	public function pushTargets( texs : Array<h3d.mat.Texture> ) {
 		pushTarget(texs[0]);
 		if( texs.length > 1 ) {
@@ -268,6 +379,10 @@ class RenderContext extends h3d.impl.RenderContext {
 		}
 	}
 
+	/**
+		Pops current render target from the target stack.
+		If last texture was removed from the stack, will restore the primary render buffer as a render target.
+	**/
 	public function popTarget() {
 		flush();
 		if( targetsStackIndex <= 0 ) throw "Too many popTarget()";
@@ -291,6 +406,12 @@ class RenderContext extends h3d.impl.RenderContext {
 		if ( tinf.hasRZ ) setRZ(tinf.rzX, tinf.rzY, tinf.rzW, tinf.rzH);
 	}
 
+	/**
+		Sets rectangular render zone area, saving previous render zone settings.
+		To respect previous render zone area, use `RenderContext.clipRenderZone` method.
+
+		`RenderContext.popRenderZone` should be called afterwards to clear render zone stack.
+	**/
 	public function pushRenderZone( x : Float, y : Float, w : Float, h : Float ) {
 		var inf = renderZoneStack[renderZoneIndex++];
 		if ( inf == null ) {
@@ -309,6 +430,9 @@ class RenderContext extends h3d.impl.RenderContext {
 		setRZ(x, y, w, h);
 	}
 
+	/**
+		Restores previous render zone settings.
+	**/
 	public function popRenderZone() {
 		if (renderZoneIndex == 0) throw "Too many popRenderZone()";
 		var inf = renderZoneStack[--renderZoneIndex];
@@ -320,9 +444,10 @@ class RenderContext extends h3d.impl.RenderContext {
 	}
 
 	/**
-	 * Same as pushRenderZone, but clips news zone to existing one before pushing it. Used so that
-	 * any call to clipRenderZone respects the already set zone ,and can't render outside it.
-	 */
+		Pushes new render zone with respect to the old render zone settings by clipping new and old render zones,
+		pushing the intersection area result.
+		Used so that any call to the clipRenderZone respects the already set zone, and can't render outside of it.
+	**/
 	 public function clipRenderZone( x : Float, y : Float, w : Float, h : Float ) {
 		if (!hasRenderZone) {
 			pushRenderZone( x, y, w, h );
@@ -374,12 +499,12 @@ class RenderContext extends h3d.impl.RenderContext {
 		engine.setRenderZone();
 	}
 
-	@:deprecated("Use pushRenderZone")
+	@:dox(hide) @:noCompletion @:deprecated("Use pushRenderZone")
 	public inline function setRenderZone( x : Float, y : Float, w : Float, h : Float ) {
 		pushRenderZone(x, y, w, h);
 	}
 
-	@:deprecated("Use popRenderZone")
+	@:dox(hide) @:noCompletion @:deprecated("Use popRenderZone")
 	public inline function clearRenderZone() {
 		popRenderZone();
 	}
@@ -388,10 +513,17 @@ class RenderContext extends h3d.impl.RenderContext {
 		@:privateAccess scene.drawLayer(this, layer);
 	}
 
+	/**
+		Renders the assigned Scene. Same as `s2d.drawRec(s2d.renderer)`.
+	**/
 	public function drawScene() {
 		@:privateAccess scene.drawRec(this);
 	}
 
+	/**
+		Flushes buffered tile data if one present.
+	**/
+	@:dox(hide)
 	public inline function flush() {
 		if( hasBuffering() ) _flush();
 	}
@@ -408,6 +540,11 @@ class RenderContext extends h3d.impl.RenderContext {
 		texture = null;
 	}
 
+	/**
+		<span class="label">Internal usage</span>
+
+		Should be called before performing a new draw call in order to sync shader data and other parameters.
+	**/
 	public function beforeDraw() {
 		if( texture == null ) texture = h3d.mat.Texture.fromColor(0xFF00FF);
 		baseShader.texture = texture;
@@ -423,7 +560,7 @@ class RenderContext extends h3d.impl.RenderContext {
 			// flash does not allow blend separate operations
 			// this will get us good color but wrong alpha
 			#else
-			// accummulate correctly alpha values
+			// accumulate correctly alpha values
 			if( blend == Alpha || blend == Add ) {
 				pass.blendAlphaSrc = One;
 				// when merging
@@ -471,6 +608,10 @@ class RenderContext extends h3d.impl.RenderContext {
 		beforeDraw();
 	}
 
+	/**
+		Prepares rendering of the Drawable object with specified texture.
+		@returns true if rendering is prepared, false otherwise (see `RenderContext.onBeginDraw`)
+	**/
 	@:access(h2d.Drawable)
 	public function beginDrawObject( obj : h2d.Drawable, texture : h3d.mat.Texture ) {
 		if ( !beginDraw(obj, texture, true) ) return false;
@@ -481,11 +622,22 @@ class RenderContext extends h3d.impl.RenderContext {
 		return true;
 	}
 
+	/**
+		Begins buffered Tile render of the Drawable object.
+		@returns true if rendering is prepared, false otherwise (see `RenderContext.onBeginDraw`)
+	**/
+	@:dox(hide)
 	@:access(h2d.Drawable)
 	public function beginDrawBatch( obj : h2d.Drawable, texture : h3d.mat.Texture ) {
 		return beginDraw(obj, texture, false);
 	}
 
+	/**
+		Renders a Tile with the transform of the given Drawable.
+
+		@returns `true` if tile was drawn, `false` otherwise.
+		Tile is not drawn if it's either outside of the rendering area or was cancelled by `RenderContext.onBeginDraw`.
+	**/
 	@:access(h2d.Drawable)
 	public function drawTile( obj : h2d.Drawable, tile : h2d.Tile ) {
 		var matA, matB, matC, matD, absX, absY;

+ 30 - 2
h2d/ScaleGrid.hx

@@ -1,18 +1,46 @@
 package h2d;
 
-class ScaleGrid extends h2d.TileGroup {
+/**
+	A simple 9-slice bitmap renderer.
 
+	Enables rendering of the Tile as a stretchable surface with unscaled corners, stretched center and either stretched or tiled borders.
+	Set `ScaleGrid.width` and `ScaleGrid.height` to resize the ScaleGrid.
+**/
+class ScaleGrid extends h2d.TileGroup {
 
+	/**
+		The width of the left and right borders in pixels.
+	**/
 	public var borderWidth(default,set) : Int;
+	/**
+		The height of the top and bottom borders in pixels.
+	**/
 	public var borderHeight(default,set) : Int;
 
+	/**
+		The width of the bitmap. Setting to values less than `borderWidth * 2` leads to undefined results.
+	**/
 	public var width(default,set) : Float;
+	/**
+		The height of the bitmap. Setting to values less than `borderHeight * 2` leads to undefined results.
+	**/
 	public var height(default,set) : Float;
-
+	/**
+		When enabled, borders will be tiled along the edges instead of stretching to match the desired dimensions.
+		
+		Center tile is always stretched.
+	**/
 	public var tileBorders(default, set) : Bool;
 
 	var contentTile : h2d.Tile;
 
+	/**
+		Create a new ScaleGrid with specified parameters.
+		@param tile The source tile which will be sliced.
+		@param borderW The width of the left and right borders in pixels.
+		@param borderH The height of the top and bottom borders in pixels.
+		@param parent An optional parent `h2d.Object` instance to which ScaleGrid adds itself if set.
+	**/
 	public function new( tile, borderW, borderH, ?parent ) {
 		super(tile,parent);
 		borderWidth = borderW;

+ 121 - 53
h2d/Scene.hx

@@ -2,24 +2,27 @@ package h2d;
 import hxd.Math;
 
 /**
-	Viewport alignment when scaling mode supports it.
+	Viewport alignment when scaling mode supports it. See `ScaleMode`.
 **/
 enum ScaleModeAlign {
-	/** Anchor Scene viewport horizontally to left side of the window. When passed to verticalAlign it will be treated as Center. **/
+	/** Anchor Scene viewport horizontally to the left side of the window. When passed to `verticalAlign` it will be treated as Center. **/
 	Left;
-	/** Anchor Scene viewport horizontally to right side of the window. When passed to verticalAlign it will be treated as Center. **/
+	/** Anchor Scene viewport horizontally to the right side of the window. When passed to `verticalAlign` it will be treated as Center. **/
 	Right;
-	/** Anchor to the center of window. **/
+	/** Anchor to the center of the window. **/
 	Center;
-	/** Anchor Scene viewport vertically to the top of a window. When passed to horizontalAlign it will be treated as Center. **/
+	/** Anchor Scene viewport vertically to the top of the window. When passed to `horizontalAlign` it will be treated as Center. **/
 	Top;
-	/** Anchor Scene viewport vertically to the bottom of a window. When passed to horizontalAlign it will be treated as Center. **/
+	/** Anchor Scene viewport vertically to the bottom of the window. When passed to `horizontalAlign` it will be treated as Center. **/
 	Bottom;
 }
 
 /**
 	Scaling mode of the 2D Scene.
-	See `ScaleMode2D` sample for showcase.
+
+	Set via `Scene.scaleMode`.
+
+	See ScaleMode2D sample for usage showcase.
 **/
 enum ScaleMode {
 
@@ -30,45 +33,74 @@ enum ScaleMode {
 
 	/**
 		Sets constant Scene size and stretches it to cover entire window. This behavior is same as old `setFixedSize` method.
+
+		@param width The width of the internal Scene viewport.
+		@param height The height of the internal Scene viewport.
 	**/
 	Stretch(width : Int, height : Int);
 
 	/**
-		Sets constant scene size and upscales it with preserving aspect-ratio to fit the window.
-		If `integerScale` is `true` - scaling will be performed  with only integer increments (1x, 2x, 3x, ...). Default: `false`
-		`horizontalAlign` controls viewport anchoring horizontally. Accepted values are `Left`, `Center` and `Right`. Default: `Center`
-		`verticalAlign` controls viewport anchoring vertically. Accepted values are `Top`, `Center` and `Bottom`. Default: `Center`
-		With `800x600` window, `LetterBox(320, 260)` will result in center-aligned Scene of size `320x260` upscaled to fit into screen.
+		Sets constant Scene size and upscales it with preserving the aspect-ratio to fit the window.
+
+		With `800x600` window, `LetterBox(320, 260)` will result in center-aligned Scene of size `320x260` upscaled to fit into the window.  
+		With same window but setting of `LetterBox(320, 260, true, Left, Top)` would result in the same Scene internal size,
+		upscaled to `640x480` resolution and anchored to the top-left corner of the window.
+
+		Note that while it's called LetterBox, there is no viewport rendering clipping apart from the out-of-bounds culling in `RenderContext.drawTile` / `Object.emitTile`.
+
+		@param width The width of the internal Scene viewport.
+		@param height The height of the internal Scene viewport.
+		@param integerScale When enabled, upscaling is performed only with integer increments (1x, 2x, 3x, etc) and can be used to achieve pixel-perfect scaling.
+		While enabled, the Scene won't be downscaled when internal viewport is larger than the window size and will remain at 1x zoom. Default: `false`.
+		@param horizontalAlign The horizontal viewport anchoring rule. Accepted values are `Left`, `Center` and `Right`. Default: `Center`.
+		@param verticalAlign The vertical viewport anchoring rule. Accepted values are `Top`, `Center` and `Bottom`. Default: `Center`.
+		
 	**/
 	LetterBox(width : Int, height : Int, ?integerScale : Bool, ?horizontalAlign : ScaleModeAlign, ?verticalAlign : ScaleModeAlign);
 
 	/**
-		Sets constant Scene size, scale and alignment. Does not perform any adaptation to the screen apart from alignment.
-		`horizontalAlign` controls viewport anchoring horizontally. Accepted values are `Left`, `Center` and `Right`. Default: `Center`
-		`verticalAlign` controls viewport anchoring vertically. Accepted values are `Top`, `Center` and `Bottom`. Default: `Center`
-		With `800x600` window, `Fixed(200, 150, 2, Left, Center)` will result in Scene size of `200x150`, and visually upscaled to `400x300`, and aligned to middle-left of the window.
+		Sets constant Scene size, scale and alignment. Does not perform any adaptation to the window size apart from alignment.
+
+		With `800x600` window, `Fixed(200, 150, 2, Left, Center)` will result in the Scene size of `200x150`, and visually upscaled to `400x300`, and aligned to a middle-left of the window.
+
+		@param width The width of the internal Scene viewport.
+		@param height The height of the internal Scene viewport.
+		@param zoom The scaling multiplier of internal viewport when rendering onto the screen.
+		@param horizontalAlign The horizontal viewport anchoring rule. Accepted values are `Left`, `Center` and `Right`. Default: `Center`.
+		@param verticalAlign The vertical viewport anchoring rule. Accepted values are `Top`, `Center` and `Bottom`. Default: `Center`.
+		
 	**/
 	Fixed(width : Int, height: Int, zoom : Float, ?horizontalAlign : ScaleModeAlign, ?verticalAlign : ScaleModeAlign);
 
 	/**
-		Upscales/downscales Scene according to `level` and matches Scene size to `ceil(window size / level)`.
-		With `800x600` window, `Zoom(2)` will result in `400x300` Scene size upscaled to fill entire window.
+		Upscales/downscales the Scene internal viewport according to `level` and matches Scene size to `ceil(window size / level)`.
+
+		With `800x600` window, `Zoom(2)` will result in the `400x300` Scene size upscaled to fill the entire window.
 	**/
 	Zoom(level : Float);
 
 	/**
-		Ensures that Scene size will be of minimum specified size.
+		Ensures that the Scene size will be of the minimum specified size.
+
 		Automatically calculates zoom level based on provided size according to `min(window width / min width, window height / min height)`, then applies same scaling as `Zoom(level)`.
-		Behavior is similiar to LetterBox, however instead of letterboxing effect, Scene size will change to cover the letterboxed parts.
+		The behavior is similar to `LetterBox`, however instead of constant internal viewport size, Scene size will change to cover the entire window.
+
 		`minWidth` or `minHeight` can be set to `0` in order to force scaling adjustment account only for either horizontal of vertical window size.
-		If `integerScale` is `true` - scaling will be performed  with only integer increments (1x, 2x, 3x, ...). Default: `false`
-		With `800x600` window, `AutoZoom(320, 260, false)` will result in Scene size of `347x260`. `AutoZoom(320, 260, true)` will result in size of `400x300`.
+		If both are `0`, results are undefined.
+
+		With `800x600` window, `AutoZoom(320, 260, false)` will result in the Scene size of `347x260`. `AutoZoom(320, 260, true)` will result in the size of `400x300`.
+		
+		@param minWidth The minimum width of the internal Scene viewport.
+		@param minHeight The minimum height of the internal Scene viewport.
+		@param integerScale When enabled, upscaling is performed only with integer increments (1x, 2x, 3x, etc) and can be used to achieve pixel-perfect scaling.
+		While enabled, the Scene won't be downscaled when internal viewport is larger than the window size and will remain at 1x zoom. Default: `false`.
+		
 	**/
 	AutoZoom(minWidth : Int, minHeight : Int, ?integerScaling : Bool);
 }
 
 /**
-	h2d.Scene is the root class for a 2D scene. All root objects are added to it before being drawn on screen.
+	The root class for a 2D scene. All root objects are added to it before being drawn on screen.
 **/
 class Scene extends Layers implements h3d.IDrawable implements hxd.SceneEvents.InteractiveScene {
 
@@ -113,68 +145,77 @@ class Scene extends Layers implements h3d.IDrawable implements hxd.SceneEvents.I
 	var offsetY(default, null) : Float;
 
 	/**
-		Horizontal scale of a scene when rendering to screen.
+		Horizontal scale of a scene when rendering to the screen.
+
 		Can change if the screen gets resized or `scaleMode` changes.
 	**/
 	public var viewportScaleX(default, null) : Float;
 	/**
-		Vertical scale of a scene when rendering to screen.
+		Vertical scale of a scene when rendering to the screen.
+
 		Can change if the screen gets resized or `scaleMode` changes.
 	**/
 	public var viewportScaleY(default, null) : Float;
 
 	/**
-		The current mouse X coordinates (in pixel) relative to the scene.
+		The current mouse X coordinates (in pixels) relative to the current `Scene.interactiveCamera`.
 	**/
 	public var mouseX(get, null) : Float;
 
 	/**
-		The current mouse Y coordinates (in pixel) relative to the scene.
+		The current mouse Y coordinates (in pixels) relative to the current `Scene.interactiveCamera`.
 	**/
 	public var mouseY(get, null) : Float;
 
 	/**
 		The zoom factor of the scene, allows to set a fixed x2, x4 etc. zoom for pixel art
-		When setting a zoom > 0, the scene resize will be automaticaly managed.
+		When setting a zoom > 0, the scene resize will be automatically managed.
 	**/
 	@:deprecated("zoom is deprecated, use scaleMode = Zoom(v) instead")
+	@:dox(hide)
 	public var zoom(get, set) : Int;
 
 	/**
-		Scene scaling mode. ( default : Resize )
+		Scene scaling mode.
+
 		Important thing to keep in mind - Scene does not clip rendering to it's scaled size and
-		graphics can render outside of it. However `drawTile` does check for those bounds and
+		graphics can render outside of it. However `RenderContext.drawTile` (and consecutively `Object.emitTile`) does check for those bounds and
 		will clip out tiles that are outside of the scene bounds.
 	**/
 	public var scaleMode(default, set) : ScaleMode = Resize;
 
 	/**
 		List of all cameras attached to the Scene. Should contain at least one camera to render (created by default).
+
 		Override `h2d.Camera.layerVisible` method to filter out specific layers from camera rendering.
-		To add or remove cameras use `addCamera` and `removeCamera` methods.
+
+		To add or remove cameras use `Scene.addCamera` and `Scene.removeCamera` methods.
 	**/
 	public var cameras(get, never) : haxe.ds.ReadOnlyArray<Camera>;
 	var _cameras : Array<Camera>;
 	/**
-		Alias to first camera in the list: `cameras[0]`
+		Alias to the first camera in the camera list: `cameras[0]`
 	**/
 	public var camera(get, never) : Camera;
 
 	/**
-		Camera instance that handles scene events.
+		Camera instance that handles the scene events.
+
 		Due to Heaps structure, only one Camera can work with the Interactives.
-		Contrary to rendering, event handling does not check if layer is visible for camera or not.
-		Should never be null. If Camera does not belong to the Scene, it will be added with `Scene.addCamera`.
+		Contrary to rendering, event handling does not check if layer is visible for the camera or not.
+
+		Should never be null. When set, if Camera does not belong to the Scene, it will be added with `Scene.addCamera`.
+		Would cause an exception when trying to remove current interactive camera from the list.
 	**/
 	public var interactiveCamera(default, set) : Camera;
 
 	/**
-		Set the default value for `h2d.Drawable.smooth` (default: false)
+		Controls the default value for `h2d.Drawable.smooth`. Default: `false`
 	**/
 	public var defaultSmooth(get, set) : Bool;
 
 	/**
-		The scene current renderer. Can be customized.
+		The current Scene renderer. Can be customized.
 	**/
 	public var renderer(get, set) : RenderContext;
 
@@ -187,7 +228,7 @@ class Scene extends Layers implements h3d.IDrawable implements hxd.SceneEvents.I
 	var shapePoint : h2d.col.Point;
 
 	/**
-		Create a new scene. A default 2D scene is already available in `hxd.App.s2d`
+		Create a new 2D scene. A default 2D scene is already available in `hxd.App.s2d`.
 	**/
 	public function new() {
 		super(null);
@@ -252,7 +293,11 @@ class Scene extends Layers implements h3d.IDrawable implements hxd.SceneEvents.I
 		return interactiveCamera = cam;
 	}
 
-	/** Adds Camera to Scene camera list with optional index at which it is added. **/
+	/**
+		Adds a Camera to the Scene camera list with optional index at which it is added.
+		@param cam The Camera instance to add.
+		@param pos Optional index at which the camera will be inserted.
+	**/
 	public function addCamera( cam : Camera, ?pos : Int ) {
 		if ( cam.scene != null )
 			cam.scene.removeCamera(cam);
@@ -262,7 +307,10 @@ class Scene extends Layers implements h3d.IDrawable implements hxd.SceneEvents.I
 		else _cameras.push(cam);
 	}
 
-	/** Removes Camera from Scene camera list. Current `interactiveCamera` cannot be removed. **/
+	/**
+		Removes the Camera from the Scene camera list.
+		Attempting to remove current `Scene.interactiveCamera` would cause an exception.
+	**/
 	public function removeCamera( cam : Camera ) {
 		if ( cam == interactiveCamera ) throw "Current interactive Camera cannot be removed from camera list!";
 		cam.scene = null;
@@ -273,10 +321,14 @@ class Scene extends Layers implements h3d.IDrawable implements hxd.SceneEvents.I
 		Set the fixed size for the scene, will prevent automatic scene resizing when screen size changes.
 	**/
 	@:deprecated("setFixedSize is deprecated, use scaleMode = Stretch(w, h) instead")
+	@:dox(hide) @:noCompletion
 	public function setFixedSize( w : Int, h : Int ) {
 		scaleMode = Stretch(w, h);
 	}
 
+	/**
+		Recalculates the scene viewport parameters based on `scaleMode`.
+	**/
 	@:dox(hide) @:noCompletion
 	public function checkResize() {
 		var engine = h3d.Engine.getCurrent();
@@ -413,7 +465,7 @@ class Scene extends Layers implements h3d.IDrawable implements hxd.SceneEvents.I
 	}
 
 	/**
-		Return the topmost visible Interactive at the specific coordinates
+		Returns the topmost visible Interactive at the specified coordinates.
 	**/
 	public function getInteractive( x : Float, y : Float ) : Interactive {
 		var pt = shapePoint;
@@ -528,14 +580,14 @@ class Scene extends Layers implements h3d.IDrawable implements hxd.SceneEvents.I
 	}
 
 	/**
-		Add an event listener that will capture all events not caught by an h2d.Interactive
+		Add an event listener that will capture all events that were not caught by an `h2d.Interactive`
 	**/
 	public function addEventListener( f : hxd.Event -> Void ) {
 		eventListeners.push(f);
 	}
 
 	/**
-		Remove a previously added event listener, return false it was not part of our event listeners.
+		Remove a previously added event listener, returns false it was not part of the event listeners.
 	**/
 	public function removeEventListener( f : hxd.Event -> Void ) {
 		for( e in eventListeners )
@@ -547,9 +599,15 @@ class Scene extends Layers implements h3d.IDrawable implements hxd.SceneEvents.I
 	}
 
 	/**
-		Start a drag and drop operation, sending all events to `onEvent` instead of the scene until `stopDrag()` is called.
-		@param	onCancel	If defined, will be called when stopDrag is called
-		@param	refEvent	For touch events, only capture events that matches the reference event touchId
+		Starts input events capture and redirects them to `onEvent` method until `Scene.stopDrag` is called.
+		
+		While the method name may imply that only mouse events would be captured: This is not the case,
+		as it will also capture all other input events, including keyboard events.
+
+		@param onEvent A callback method that receives `hxd.Event` when input event happens.
+		Unless `onEvent` sets `Event.propagate` to `true`, event won't be sent to other Interactives.
+		@param onCancel An optional callback that is invoked when `Scene.stopDrag` is called.
+		@param refEvent For touch events, when defined, only capture events that match the reference `Event.touchId`.
 	**/
 	public function startDrag( onEvent : hxd.Event -> Void, ?onCancel : Void -> Void, ?refEvent : hxd.Event ) {
 		events.startDrag(function(e) {
@@ -559,14 +617,14 @@ class Scene extends Layers implements h3d.IDrawable implements hxd.SceneEvents.I
 	}
 
 	/**
-		Stop the current drag and drop operation
+		Stops current input event capture.
 	**/
 	public function stopDrag() {
 		events.stopDrag();
 	}
 
 	/**
-		Get the currently focused Interactive
+		Get the currently focused Interactive.
 	**/
 	public function getFocus() : Interactive {
 		if( events == null )
@@ -580,6 +638,7 @@ class Scene extends Layers implements h3d.IDrawable implements hxd.SceneEvents.I
 		return interactive[interactive.indexOf(i)];
 	}
 
+
 	@:allow(h2d)
 	function addEventTarget(i:Interactive) {
 		// sort by which is over the other in the scene hierarchy
@@ -640,7 +699,9 @@ class Scene extends Layers implements h3d.IDrawable implements hxd.SceneEvents.I
 	}
 
 	/**
-		Dispose the scene and all its children, freeing used GPU memory
+		Dispose the scene and all its children, freeing used GPU memory.
+
+		If Scene was allocated, causes `Object.onRemove` on all Scene objects.
 	**/
 	public function dispose() {
 		if( allocated )
@@ -649,8 +710,10 @@ class Scene extends Layers implements h3d.IDrawable implements hxd.SceneEvents.I
 	}
 
 	/**
-		Before render() or sync() are called, allow to set how much time has elapsed (in seconds) since the last frame in order to update scene animations.
-		This is managed automatically by hxd.App
+		<span class="label">Internal usage</span>
+
+		Before `Scene.render` or `Scene.sync` are called, allows to set how much time has elapsed (in seconds) since the last frame in order to update scene animations.
+		This is managed automatically by hxd.App.
 	**/
 	public function setElapsedTime( v : Float ) {
 		ctx.elapsedTime = v;
@@ -688,7 +751,9 @@ class Scene extends Layers implements h3d.IDrawable implements hxd.SceneEvents.I
 	}
 
 	/**
-		Render the scene on screen. Internal usage only.
+		<span class="label">Internal usage</span>
+
+		Render the scene on the screen.
 	**/
 	public function render( engine : h3d.Engine ) {
 		ctx.engine = engine;
@@ -785,7 +850,10 @@ class Scene extends Layers implements h3d.IDrawable implements hxd.SceneEvents.I
 	}
 
 	/**
-		Capture the scene into a texture and render the resulting Bitmap
+		Capture the scene into a texture and returns the resulting `h2d.Bitmap`.
+		
+		@param target Optional Tile to render onto. If not set, new Texture with interval Scene viewport dimensions is allocated,
+		otherwise Tile boundaries and Texture are used.
 	**/
 	public function captureBitmap( ?target : Tile ) {
 		var engine = h3d.Engine.getCurrent();

+ 35 - 0
h2d/Slider.hx

@@ -1,13 +1,43 @@
 package h2d;
 
+/**
+	A simple interactive horizontal numerical slider.
+**/
 class Slider extends h2d.Interactive {
+	/**
+		The slider background tile.
 
+		If Tile width does not match with Slider width, it will be resized through `Tile.setSize` to match the Slider width.
+		
+		Defaults to the monocolor 0x808080 Tile with the size of `Slider.width x 4` and centered vertically within `Slider.height`.
+	**/
 	public var tile : h2d.Tile;
+	/**
+		Tile of the slider current position caret.
+
+		Defaults to the monocolor #CCCCCC Tile with the size of `5 x Slider.height`.
+	**/
 	public var cursorTile : h2d.Tile;
+	/**
+		The minimum value the Slider can allow.
+	**/
 	public var minValue(default, set) : Float = 0;
+	/**
+		The maximum value the Slider can allow.
+	**/
 	public var maxValue(default, set) : Float = 1;
+	/**
+		Current value of the Slider.
+		When set, will be clamped to `minValue <= value <= maxValue`.
+	**/
 	public var value(default, set) : Float = 0;
 
+	/**
+		Create a new Slider width specified dimensions and parent.
+		@param width The width of the Slider interactive area.
+		@param height The height of the Slider interactive area.
+		@param parent An optional parent `h2d.Object` instance to which Sliders adds itself if set.
+	**/
 	public function new(?width:Int = 50, ?height:Int = 10, ?parent) {
 		super(width, height, parent);
 
@@ -90,6 +120,11 @@ class Slider extends h2d.Interactive {
 		}
 	}
 
+	/**
+		Sent when slider value is changed by user.
+
+		Not sent if value is set manually from software side.
+	**/
 	public dynamic function onChange() {
 	}
 

+ 1 - 0
h2d/Sprite.hx

@@ -3,5 +3,6 @@ package h2d;
 #if !heaps_sprite
 @:deprecated("h2d.Sprite is now h2d.Object, rename or use -D heaps-sprite")
 @:noCompletion
+@:dox(hide)
 #end
 typedef Sprite = Object;

+ 155 - 18
h2d/SpriteBatch.hx

@@ -18,30 +18,90 @@ private class ElementsIterator {
 	}
 }
 
+/**
+	A base class for `SpriteBatch` elements which can be extended with custom logic.
+
+	See `BasicElement` as an example of custom element logic.
+**/
 @:allow(h2d.SpriteBatch)
 class BatchElement {
-	public var x : Float;
-	public var y : Float;
+	/**
+		Element X position.
+	**/
+	public var x : Float = 0;
+	/**
+		Element Y position.
+	**/
+	public var y : Float = 0;
+	/**
+		Shortcut to set both `BatchElement.scaleX` and `BatchElement.scaleY` at the same time.
+
+		Equivalent to `el.scaleX = el.scaleY = scale`.
+	**/
 	public var scale(never,set) : Float;
-	public var scaleX : Float;
-	public var scaleY : Float;
-	public var rotation : Float;
-	public var r : Float;
-	public var g : Float;
-	public var b : Float;
-	public var a : Float;
+	/**
+		X-axis scaling factor of the element.
+
+		This variable is used only if `SpriteBatch.hasRotationScale` is set to `true`.
+	**/
+	public var scaleX : Float = 1;
+	/**
+		Y-axis scaling factor of the element.
+
+		This variable is used only if `SpriteBatch.hasRotationScale` is set to `true`.
+	**/
+	public var scaleY : Float = 1;
+	/**
+		Element rotation in radians.
+
+		This variable is used only if `SpriteBatch.hasRotationScale` is set to `true`.
+	**/
+	public var rotation : Float = 0;
+	/**
+		Red tint value (0...1 range) of the element.
+	**/
+	public var r : Float = 1;
+	/**
+		Green tint value (0...1 range) of the element.
+	**/
+	public var g : Float = 1;
+	/**
+		Blue tint value (0...1 range) of the element.
+	**/
+	public var b : Float = 1;
+	/**
+		Alpha value of the element.
+	**/
+	public var a : Float = 1;
+	/**
+		The Tile this element renders.
+
+		Due to implementation specifics, this Tile instance is used only to provide rendering area, not the Texture itself,
+		as `SpriteBatch.tile` used as a source of rendered texture.
+	**/
 	public var t : Tile;
+	/**
+		Alpha value of the element.
+		Alias of `BatchElement.a`.
+	**/
 	public var alpha(get,set) : Float;
-	public var visible : Bool;
+	/**
+		If set to `false`, element will not be rendered.
+	**/
+	public var visible : Bool = true;
+	/**
+		Reference to parent SpriteBatch instance.
+	**/
 	public var batch(default, null) : SpriteBatch;
 
 	var prev : BatchElement;
 	var next : BatchElement;
 
-	public function new(t) {
-		x = 0; y = 0; r = 1; g = 1; b = 1; a = 1;
-		rotation = 0; scaleX = scaleY = 1;
-		visible = true;
+	/**
+		Create a new BatchElement instance with provided Tile.
+		@param t The tile used to render this BatchElement.
+	**/
+	public function new( t : Tile ) {
 		this.t = t;
 	}
 
@@ -57,10 +117,20 @@ class BatchElement {
 		return a = v;
 	}
 
+	/**
+		Override this method to perform custom logic per batch element.
+		Update method called only if `SpriteBatch.hasUpdate` is set to `true`.
+		@param dt The elapsed time in seconds since last update from `RenderContext.elapsedTime`.
+		@returns If method returns `false`, element will be removed from the SpriteBatch.
+	**/
+	@:dox(show)
 	function update(et:Float) {
 		return true;
 	}
 
+	/**
+		Remove this BatchElement from the parent SpriteBatch instance.
+	**/
 	public function remove() {
 		if( batch != null )
 			batch.delete(this);
@@ -68,11 +138,29 @@ class BatchElement {
 
 }
 
+/**
+	A simple `BatchElement` that provides primitive simulation of velocity, friction and gravity.
+
+	Parent `SpriteBatch` should have `SpriteBatch.hasUpdate` set to `true` in order for BasicElement to work properly.
+**/
 class BasicElement extends BatchElement {
 
+	/**
+		X-axis velocity of the element.
+	**/
 	public var vx : Float = 0.;
+	/**
+		Y-axis velocity of the element.
+	**/
 	public var vy : Float = 0.;
+	/**
+		The velocity friction.
+		When not `1`, multiplies velocity by `pow(friction, dt * 60)`.
+	**/
 	public var friction : Float = 1.;
+	/**
+		The gravity applied to vertical velocity in pixels per second.
+	**/
 	public var gravity : Float = 0.;
 
 	override function update(dt:Float) {
@@ -89,11 +177,33 @@ class BasicElement extends BatchElement {
 
 }
 
+/**
+	An active batched tile renderer.
+	
+	Compared to `TileGroup` which is expected to be used as a static geometry,
+	SpriteBatch uploads GPU buffer each frame by collecting data from added `BatchElement` instance.
+	Due to that, dynamically removing and adding new geometry is fairly simple.
+
+	Usage note: While SpriteBatch allows for multiple unique textures, each texture swap causes a new drawcall,
+	and due to that it's recommended to minimize the amount of used textures per SpriteBatch instance,
+	ideally limiting to only one texture.
+**/
 class SpriteBatch extends Drawable {
 
+	/**
+		The Tile used as a base Texture to draw contents with.
+	**/
 	public var tile : Tile;
-	public var hasRotationScale : Bool;
-	public var hasUpdate : Bool;
+	/**
+		Enables usage of rotation and scaling of SpriteBatch elements at the cost of extra calculus.
+
+		Makes use of `BatchElement.scaleX`, `BatchElement.scaleY` and `BatchElement.rotation`.
+	**/
+	public var hasRotationScale : Bool = false;
+	/**
+		Enables usage of `update` method in SpriteBatch elements.
+	**/
+	public var hasUpdate : Bool = false;
 	var first : BatchElement;
 	var last : BatchElement;
 	var tmpBuf : hxd.FloatBuffer;
@@ -101,12 +211,22 @@ class SpriteBatch extends Drawable {
 	var state : BatchDrawState;
 	var empty : Bool;
 
+	/**
+		Create new SpriteBatch instance.
+		@param t The Tile used as a base Texture to draw contents with.
+		@param parent An optional parent `h2d.Object` instance to which SpriteBatch adds itself if set.
+	**/
 	public function new(t,?parent) {
 		super(parent);
 		tile = t;
 		state = new BatchDrawState();
 	}
 
+	/**
+		Adds a new BatchElement to the SpriteBatch.
+		@param e The element to add.
+		@param before When set, element will be added to the beginning of the element chain (rendered first).
+	**/
 	public function add(e:BatchElement,before=false) {
 		e.batch = this;
 		if( first == null ) {
@@ -126,12 +246,21 @@ class SpriteBatch extends Drawable {
 		return e;
 	}
 
+	/**
+		Removes all elements from the SpriteBatch.
+
+		Usage note: Does not clear the `BatchElement.batch` nor `next`/`prev` variables on the child elements.
+	**/
 	public function clear() {
 		first = last = null;
 		flush();
 	}
 
-	public function alloc(t) {
+	/**
+		Creates a new BatchElement and returns it. Shortcut to `add(new BatchElement(t))`
+		@param t The Tile element will render.
+	**/
+	public function alloc( t : Tile ) : BatchElement {
 		return add(new BatchElement(t));
 	}
 
@@ -324,15 +453,23 @@ class SpriteBatch extends Drawable {
 		state.drawQuads(ctx, buffer);
 	}
 
+	/**
+		Checks if SpriteBatch contains any elements.
+	**/
 	public inline function isEmpty() {
 		return first == null;
 	}
 
+	/**
+		Returns an Iterator of all SpriteBatch elements.
+
+		Adding or removing the elements will affect the Iterator results.
+	**/
 	public inline function getElements() {
 		return new ElementsIterator(first);
 	}
 
-	override function onRemove()  {
+	override function onRemove() {
 		super.onRemove();
 		if( buffer != null ) {
 			buffer.dispose();

+ 111 - 7
h2d/Text.hx

@@ -1,26 +1,112 @@
 package h2d;
 
+/**
+	`Text` alignment rules.
+**/
 enum Align {
+	/**
+		Aligns the text to the left edge.
+	**/
 	Left;
+	/**
+		Aligns the text to the right edge.
+
+		When `Text.maxWidth` is set and/or Text size is constrained (see `Object.constraintSize`), right edge is considered the smallest of the two.
+
+		Otherwise edge is at the `0` coordinate of the Text instance.
+		
+		See Text sample for showcase.
+	**/
 	Right;
+	/**
+		Centers the text alignment.
+		
+		When `Text.maxWidth` is set and/or Text size is constrained (see `Object.constraintSize`), center is calculated from 0 to the smallest of the two.
+
+		Otherwise text is centered around `0` coordinate of the Text instance.
+
+		See Text sample for showcase.
+	**/
 	Center;
+	/**
+		With respect to Text constraints, aligns the text to the right edge of the longest line width.
+
+		When `Text.maxWidth` is set and/or Text size is constrained (see `Object.constraintSize`),
+		right edge is calculated as the smallest value of the `maxWidth`, constrained width and longest line width (after word-wrap from constraints).
+
+		Otherwise uses longest line width as the right edge.
+
+		See Text sample for showcase.
+	**/
 	MultilineRight;
+	/**
+		Centers the text with respect to Text constraints with the longest line width.
+
+		When `Text.maxWidth` is set and/or Text size is constrained (see `Object.constraintSize`),
+		center is calculated from the to the smallest value of the `maxWidth`, constrained width and longest line width (after word-wrap from constraints).
+
+		Otherwise calculates center from 0 to the longest line width.
+
+		See Text sample for showcase.
+	**/
 	MultilineCenter;
 }
 
-class Text extends Drawable {
+/**
+	A basic text renderer with multiline support.
 
+	See [Text](https://github.com/HeapsIO/heaps/wiki/Text) section of the manual for more details.
+**/
+class Text extends Drawable {
+	/**
+		The font used to render text.
+	**/
 	public var font(default, set) : Font;
+	/**
+		Current rendered text.
+	**/
 	public var text(default, set) : String;
+	/**
+		Text RGB color. Alpha value is ignored.
+	**/
 	public var textColor(default, set) : Int;
+	/**
+		When set, limits maximum line width and causes word-wrap.
+		Affects positioning of the text depending on `textAlign` value.
+
+		When Text is affected by size constraints (see `Object.constraintSize`), smallest of the two is used for word-wrap.
+	**/
 	public var maxWidth(default, set) : Null<Float>;
+	/**
+		Adds simple drop shadow to the Text with specified offset, color and alpha.
+		Causes text to be rendered twice (first drop shadow and then the text itself).
+	**/
 	public var dropShadow : { dx : Float, dy : Float, color : Int, alpha : Float };
 
+	/**
+		Calculated text width. Can exceed maxWidth in certain cases.
+	**/
 	public var textWidth(get, null) : Float;
+	/**
+		Calculated text height.
+		
+		Not a completely precise text metric and increments in the `Font.lineHeight` steps.
+		In `HtmlText`, can be increased by various values depending on the active line font and `HtmlText.lineHeightMode` value.
+	**/
 	public var textHeight(get, null) : Float;
+	/**
+		Text align rules dictate how the text lines are positioned.
+		See `Align` for specific details on each alignment mode.
+	**/
 	public var textAlign(default, set) : Align;
-	public var letterSpacing(default, set) : Float;
-	public var lineSpacing(default,set) : Float;
+	/**
+		Extra letter spacing in pixels.
+	**/
+	public var letterSpacing(default, set) : Float = 0;
+	/**
+		Extra line spacing in pixels.
+	**/
+	public var lineSpacing(default,set) : Float = 0;
 
 	var glyphs : TileGroup;
 	var needsRebuild : Bool;
@@ -38,12 +124,15 @@ class Text extends Drawable {
 
 	var sdfShader : h3d.shader.SignedDistanceField;
 
+	/**
+		Creates a new Text instance.
+		@param font The font used to render the Text.
+		@param parent An optional parent `h2d.Object` instance to which Text adds itself if set.
+	**/
 	public function new( font : Font, ?parent : h2d.Object ) {
 		super(parent);
 		this.font = font;
 		textAlign = Left;
-		letterSpacing = 0;
-		lineSpacing = 0;
 		text = "";
 		currentText = "";
 		textColor = 0xFFFFFF;
@@ -158,6 +247,12 @@ class Text extends Drawable {
 		return t;
 	}
 
+	/**
+		Extra validation of the `text` variable when it's changed. Override to add custom validation.
+
+		Only validation of the text is allowed, and attempting to change the text value will lead to undefined behavior.
+	**/
+	@:dox(show)
 	function validateText() {
 	}
 
@@ -167,6 +262,9 @@ class Text extends Drawable {
 		onContentChanged();
 	}
 
+	/**
+		Calculates and returns width of the provided `text` with settings this Text instance.
+	**/
 	public function calcTextWidth( text : String ) {
 		if( calcDone ) {
 			var ow = calcWidth, oh = calcHeight, osh = calcSizeHeight, ox = calcXMin, oy = calcYMin;
@@ -186,14 +284,15 @@ class Text extends Drawable {
 	}
 
 	/**
-		Word-wrap the text based on this Text settings.		
+		Perform a word-wrap of the `text` based on this Text settings.
 	**/
 	public function splitText( text : String ) {
 		return splitRawText(text,0,0);
 	}
 
 	/**
-		Word-wrap the text based on this Text settings.  
+		<span class="label">Advanced usage</span>  
+		Perform a word-wrap of the text based on this Text settings.
 		@param text String to word-wrap.
 		@param leftMargin Starting x offset of the first line.
 		@param afterData Minimum remaining space required at the end of the line.
@@ -201,6 +300,7 @@ class Text extends Drawable {
 		@param sizes Optional line width array. Will be populated with sizes of split lines if present. Sizes will include both `leftMargin` in it's first line entry.
 		@param prevChar Optional character code for concatenation purposes (proper kernings).
 	**/
+	@:dox(show)
 	function splitRawText( text : String, leftMargin = 0., afterData = 0., ?font : Font, ?sizes:Array<Float>, ?prevChar:Int = -1 ) {
 		var maxWidth = realMaxWidth;
 		if( maxWidth < 0 ) {
@@ -272,6 +372,10 @@ class Text extends Drawable {
 		return lines.join("\n");
 	}
 
+	/**
+		Returns cut `text` based on `progress` percentile.
+		Can be used to gradually show appearing text. (Especially useful when using `HtmlText`)
+	**/
 	public function getTextProgress( text : String, progress : Float ) {
 		if( progress >= text.length ) return text;
 		return text.substr(0, Std.int(progress));

+ 83 - 1
h2d/TextInput.hx

@@ -3,16 +3,48 @@ import hxd.Key in K;
 
 private typedef TextHistoryElement = { t : String, c : Int, sel : { start : Int, length : Int } };
 
+/**
+	A skinnable text input handler.
+
+	Supports text selection, keyboard cursor navigation, as well as basic hotkeys: `Ctrl + Z`, `Ctrl + Y` for undo and redo and `Ctrl + A` to select all text.
+**/
 class TextInput extends Text {
 
+	/**
+		Current position of the input cursor.
+		When TextInput is not focused value is -1.
+	**/
 	public var cursorIndex : Int = -1;
+	/**
+		The Tile used to render the input cursor.
+	**/
 	public var cursorTile : h2d.Tile;
+	/**
+		The Tile used to render the background for selected text.
+		When rendering, this Tile is stretched horizontally to fill entire selection area.
+	**/
 	public var selectionTile : h2d.Tile;
+	/**
+		The blinking interval of the cursor in seconds.
+	**/
 	public var cursorBlinkTime = 0.5;
+	/**
+		Maximum input width.
+		Contrary to `Text.maxWidth` does not cause a word-wrap, but also masks out contents that are outside the max width.
+	**/
 	public var inputWidth : Null<Int>;
+	/**
+		If not null, represents current text selection range.
+	**/
 	public var selectionRange : { start : Int, length : Int };
+	/**
+		When disabled, user would not be able to edit the input text (selection is still available).
+	**/
 	public var canEdit = true;
 
+	/**
+		If set, TextInput will render provided color as a background to text interactive area.
+	**/
 	public var backgroundColor(get, set) : Null<Int>;
 
 	var interactive : h2d.Interactive;
@@ -30,6 +62,11 @@ class TextInput extends Text {
 	var lastClick = 0.;
 	var maxHistorySize = 100;
 
+	/**
+		Create a new TextInput instance.
+		@param font The font used to render the text.
+		@param parent An optional parent `h2d.Object` instance to which TextInput adds itself if set.
+	**/
 	public function new(font, ?parent) {
 		super(font, parent);
 		interactive = new h2d.Interactive(0, 0);
@@ -261,7 +298,10 @@ class TextInput extends Text {
 		while( undo.length > maxHistorySize ) undo.shift();
 	}
 
-	public function getSelectedText() {
+	/**
+		Returns a String representing currently selected text area or `null` if no text is selected.
+	**/
+	public function getSelectedText() : String {
 		return selectionRange == null ? null : text.substr(selectionRange.start, selectionRange.length);
 	}
 
@@ -354,6 +394,9 @@ class TextInput extends Text {
 			ctx.popRenderZone();
 	}
 
+	/**
+		Sets focus on this `TextInput`.
+	**/
 	public function focus() {
 		interactive.focus();
 		if( cursorIndex < 0 ) {
@@ -362,43 +405,82 @@ class TextInput extends Text {
 		}
 	}
 
+	/**
+		Checks if TextInput is currently focused.
+	**/
 	public function hasFocus() {
 		return interactive.hasFocus();
 	}
 
+	/**
+		Delegate of underlying `Interactive.onOut`.
+	**/
 	public dynamic function onOut(e:hxd.Event) {
 	}
 
+	/**
+		Delegate of underlying `Interactive.onOver`.
+	**/
 	public dynamic function onOver(e:hxd.Event) {
 	}
 
+	/**
+		Delegate of underlying `Interactive.onMove`.
+	**/
 	public dynamic function onMove(e:hxd.Event) {
 	}
 
+	/**
+		Delegate of underlying `Interactive.onClick`.
+	**/
 	public dynamic function onClick(e:hxd.Event) {
 	}
 
+	/**
+		Delegate of underlying `Interactive.onPush`.
+	**/
 	public dynamic function onPush(e:hxd.Event) {
 	}
 
+	/**
+		Delegate of underlying `Interactive.onRelease`.
+	**/
 	public dynamic function onRelease(e:hxd.Event) {
 	}
 
+	/**
+		Delegate of underlying `Interactive.onKeyDown`.
+	**/
 	public dynamic function onKeyDown(e:hxd.Event) {
 	}
 
+	/**
+		Delegate of underlying `Interactive.onKeyUp`.
+	**/
 	public dynamic function onKeyUp(e:hxd.Event) {
 	}
 
+	/**
+		Delegate of underlying `Interactive.onTextInput`.
+	**/
 	public dynamic function onTextInput(e:hxd.Event) {
 	}
 
+	/**
+		Delegate of underlying `Interactive.onFocus`.
+	**/
 	public dynamic function onFocus(e:hxd.Event) {
 	}
 
+	/**
+		Delegate of underlying `Interactive.onFocusLost`.
+	**/
 	public dynamic function onFocusLost(e:hxd.Event) {
 	}
 
+	/**
+		Sent when user modifies TextInput contents.
+	**/
 	public dynamic function onChange() {
 	}
 

+ 169 - 4
h2d/Tile.hx

@@ -1,5 +1,15 @@
 package h2d;
 
+/**
+	A core 2D rendering component representing a region of an underlying `h3d.mat.Texture`.
+
+	Tiles cannot be created directly, and instances are created with the following methods:
+	* Via the Resource Management system: `hxd.res.Image.toTile`.
+	* From pre-existing Texture: `Tile.fromTexture`.
+	* From pre-existing `BitmapData` or `Pixels`: `Tile.fromBitmap` and `Tile.fromPixels` (as well as `Tile.autoCut`).
+	* From solid color: `Tile.fromColor`.
+	* From previously existing Tile instance via various methods, such as `Tile.sub`.
+**/
 @:allow(h2d)
 class Tile {
 
@@ -10,25 +20,77 @@ class Tile {
 	var u2 : Float;
 	var v2 : Float;
 
+	/**
+		Visual offset of the Tile along the X axis during rendering.
+	**/
 	public var dx : Float;
+	/**
+		Visual offset of the Tile along the Y axis during rendering.
+	**/
 	public var dy : Float;
+	/**
+		Horizontal position of the Tile on the Texture.
+
+		Cannot be modified directly, use `Tile.setPosition` instead.
+	**/
 	public var x(default,null) : Float;
+	/**
+		Vertical position of the Tile on the Texture.
+
+		Cannot be modified directly, use `Tile.setPosition` instead.
+	**/
 	public var y(default,null) : Float;
+	/**
+		Width of the Tile.
+		Not guaranteed to represent real width of the Tile on texture. (see `Tile.scaleToSize`)
+
+		Cannot be modified directly, use `Tile.setSize` instead.
+	**/
 	public var width(default,null) : Float;
+	/**
+		Height of the Tile.
+		Not guaranteed to represent real height of the Tile on texture. (see `Tile.scaleToSize`)
+
+		Cannot be modified directly, use `Tile.setSize` instead.
+	**/
 	public var height(default,null) : Float;
 	
+	/**
+		The flip state of the Tile.
+		@see `Tile.flipX`
+	**/
 	public var xFlip(get,set) : Bool;
+	/**
+		The flip state of the Tile.
+		@see `Tile.flipY`
+	**/
 	public var yFlip(get,set) : Bool;
 
+	/**
+		An integer horizontal position of the Tile on the Texture.
+		Alias to `Math.floor(tile.x)`.
+	**/
 	public var ix(get,never) : Int;
 	inline function get_ix() return Math.floor(x);
 
+	/**
+		An integer vertical position of the Tile on the Texture.
+		Alias to `Math.floor(tile.y)`.
+	**/
 	public var iy(get,never) : Int;
 	inline function get_iy() return Math.floor(y);
 
+	/**
+		An integer width of the Tile.
+		Alias to `Math.ceil(tile.width + tile.x) - tile.ix`.
+	**/
 	public var iwidth(get,never) : Int;
 	inline function get_iwidth() return Math.ceil(width + x) - ix;
 
+	/**
+		An integer height of the Tile.
+		Alias to `Math.ceil(tile.height + tile.y) - tile.iy`.
+	**/
 	public var iheight(get,never) : Int;
 	inline function get_iheight() return Math.ceil(height + y) - iy;
 
@@ -43,10 +105,16 @@ class Tile {
 		if( tex != null ) setTexture(tex);
 	}
 
+	/**
+		Returns an underlying Texture instance.
+	**/
 	public inline function getTexture():h3d.mat.Texture {
 		return innerTex;
 	}
 
+	/**
+		Checks if Tile or underlying Texture were disposed.
+	**/
 	public function isDisposed() {
 		return innerTex == null || innerTex.isDisposed();
 	}
@@ -61,33 +129,71 @@ class Tile {
 		}
 	}
 
+	/**
+		Changes this Tile underlying texture to one used in the specified Tile.
+
+		If Tile was scaled, new uv will cover new width and height instead of the original unscaled one.
+
+		@param t The Tile used as a source of the Texture instance.
+
+		It's possible to switch texture by referring the Texture instance directly, by using access hacks:
+		```haxe
+		@:privateAccess tile.setTexture(myTextureInstance);
+		```
+	**/
 	public inline function switchTexture( t : Tile ) {
 		setTexture(t.innerTex);
 	}
 
+	/**
+		Create a sub-region of this Tile with specified size and offset.
+		@param x The offset on top of the current Tile offset along the X axis.
+		@param y The offset on top of the current Tile offset along the Y axis.
+		@param w The width of the new Tile region. Can exceed current tile size.
+		@param h The height of the new Tile region. Can exceed the current tile size.
+		@param dx An optional visual offset of the new Tile along the X axis.
+		@param dy An optional visual offset of the new Tile along the Y axis.
+	**/
 	public function sub( x : Float, y : Float, w : Float, h : Float, dx = 0., dy = 0. ) : Tile {
 		return new Tile(innerTex, this.x + x, this.y + y, w, h, dx, dy);
 	}
 
+	/**
+		Returns a new Tile with shifting origin point (`dx` and `dy`) to the tile center.
+
+		To modify this Tile origin point, use `Tile.setCenterRatio`.
+	**/
 	public function center():Tile {
 		return sub(0, 0, width, height, -(width * .5), -(height * .5));
 	}
 
+	/**
+		Sets `dx` / `dy` as origin point dictated by `px` / `py` with a default being center.
+	**/
 	public inline function setCenterRatio(?px:Float=0.5, ?py:Float=0.5) : Void {
 		dx = -(px*width);
 		dy = -(py*height);
 	}
 
+	/**
+		Flips the Tile horizontally. Note that `dx` is flipped as well.
+	**/
 	public function flipX() : Void {
 		var tmp = u; u = u2; u2 = tmp;
 		dx = -dx - width;
 	}
 
+	/**
+		Flips the Tile vertically. Note that `dy` is flipped as well.
+	**/
 	public function flipY() : Void {
 		var tmp = v; v = v2; v2 = tmp;
 		dy = -dy - height;
 	}
 
+	/**
+		Set the Tile position in the texture to the specified coordinate.
+	**/
 	public function setPosition(x : Float, y : Float) : Void {
 		this.x = x;
 		this.y = y;
@@ -100,6 +206,9 @@ class Tile {
 		}
 	}
 
+	/**
+		Set the Tile size in the texture to the specified dimensions.
+	**/
 	public function setSize(w : Float, h : Float) : Void {
 		this.width = w;
 		this.height = h;
@@ -110,11 +219,21 @@ class Tile {
 		}
 	}
 
+	/**
+		Rescales the Tile to be of the set width and height, but without affecting the uv coordinates.
+
+		Using this method allows to upscale/downscale Tiles, but creates a mismatch between the tile uv and width/height values.
+		Due to that, using any methods that modify the uv value will cause the new uv to treat scaled width and height as true dimensions
+		and can lead to unexpected results if not accounted for.
+	**/
 	public function scaleToSize( w : Float, h : Float ) : Void {
 		this.width = w;
 		this.height = h;
 	}
 
+	/**
+		Scrolls the texture position by specified amount.
+	**/
 	public function scrollDiscrete( dx : Float, dy : Float ) : Void {
 		var tex = innerTex;
 		u += dx / tex.width;
@@ -125,11 +244,18 @@ class Tile {
 		y = v * tex.height;
 	}
 
+	/**
+		Disposes of the Tile and its underlying Texture.
+		Note that if Texture is used by other Tile instances, it will cause them to point at a disposed texture and can lead to errors.
+	**/
 	public function dispose() : Void {
 		if( innerTex != null ) innerTex.dispose();
 		innerTex = null;
 	}
 
+	/**
+		Create a copy of this Tile instance.
+	**/
 	public function clone() : Tile {
 		var t = new Tile(null, x, y, width, height, dx, dy);
 		t.innerTex = innerTex;
@@ -152,7 +278,10 @@ class Tile {
 	}
 
 	/**
-		Split horizontaly or verticaly the number of given frames
+		Split the Tile horizontally or vertically by the number of given frames.
+		@param frames The amount of frames this Tile has to be split into.
+		@param vertical Causes split to be done vertically instead of horizontal split.
+		@param subpixel When enabled, retains the floating-point remainder if calculated frame size is not integral.
 	**/
 	public function split( frames : Int = 0, vertical = false, subpixel = false ) : Array<Tile> {
 		var tl = [];
@@ -174,7 +303,11 @@ class Tile {
 
 	/**
 		Split the tile into a list of tiles of Size x Size pixels.
-		Unlike grid which is X/Y ordered, gridFlatten returns a single dimensional array ordered in Y/X.
+		
+		@param size The width and height of the new Tiles.
+		@param dx Optional visual offset of the new Tiles along the X axis.
+		@param dy Optional visual offset of the new Tiles along the Y axis.
+		@returns A one-dimensional array ordered in Y/X.
 	**/
 	public function gridFlatten( size : Float, dx = 0., dy = 0. ) : Array<Tile> {
 		return [for( y in 0...Std.int(height / size) ) for( x in 0...Std.int(width / size) ) sub(x * size, y * size, size, size, dx, dy)];
@@ -182,11 +315,17 @@ class Tile {
 
 	/**
 		Split the tile into a list of tiles of Size x Size pixels.
+
+		@param size The width and height of the new Tiles.
+		@param dx Optional visual offset of the new Tiles along the X axis.
+		@param dy Optional visual offset of the new Tiles along the Y axis.
+		@returns A two-dimensional array ordered in `[X][Y]`.
 	**/
 	public function grid( size : Float, dx = 0., dy = 0. ) : Array<Array<Tile>> {
 		return [for( x in 0...Std.int(width / size) ) [for( y in 0...Std.int(height / size) ) sub(x * size, y * size, size, size, dx, dy)]];
 	}
 
+	@:dox(hide)
 	public function toString() : String {
 		return "Tile(" + x + "," + y + "," + width + "x" + height + (dx != 0 || dy != 0 ? "," + dx + ":" + dy:"") + ")";
 	}
@@ -207,7 +346,13 @@ class Tile {
 		innerTex.uploadBitmap(bmp);
 	}
 
-
+	/**
+		Create a solid color Tile with specified width, height, color and alpha.
+		@param color The RGB color of the Tile.
+		@param width The width of the Tile in pixels.
+		@param height The height of the Tile in pixels.
+		@param alpha The transparency of the Tile.
+	**/
 	public static function fromColor( color : Int, ?width = 1, ?height = 1, ?alpha = 1. ) : Tile {
 		var t = new Tile(h3d.mat.Texture.fromColor(color,alpha),0,0,1,1);
 		// scale to size
@@ -216,12 +361,26 @@ class Tile {
 		return t;
 	}
 
+	/**
+		Creates a new Texture from provided BitmapData and returns a Tile representing it.
+	**/
 	public static function fromBitmap( bmp : hxd.BitmapData ) : Tile {
 		var tex = h3d.mat.Texture.fromBitmap(bmp);
 		return new Tile(tex, 0, 0, bmp.width, bmp.height);
 	}
 
-	public static function autoCut( bmp : hxd.BitmapData, width : Int, ?height : Int ) {
+	/**
+		Creates a new POT Texture from bmp and cuts it in a grid of tiles with maximum size of `[width, height]`.
+
+		Algorithm will use bottom-right pixels as background color and cut out empty space from each Tile and
+		will modify the origin point to retain the Tile position.
+		Each row scan continues as long as there are no empty tiles.
+
+		@param bmp The BitmapData which will be split into tiles.
+		@param width The width of a single grid entry.
+		@param height An optional height of a single grid entry. Width will be used if not provided.
+	**/
+	public static function autoCut( bmp : hxd.BitmapData, width : Int, ?height : Int ) : { main: Tile, tiles: Array<Array<Tile>> } {
 		#if js
 		bmp.lock();
 		#end
@@ -252,10 +411,16 @@ class Tile {
 		return { main : main, tiles : tl };
 	}
 
+	/**
+		Create new Tile from provided Texture instance.
+	**/
 	public static function fromTexture( t : h3d.mat.Texture ) : Tile {
 		return new Tile(t, 0, 0, t.width, t.height);
 	}
 
+	/**
+		Creates new POT Texture from Pixels and returns a Tile representing it.
+	**/
 	public static function fromPixels( pixels : hxd.Pixels ) : Tile {
 		var pix2 = pixels.makeSquare(true);
 		var t = h3d.mat.Texture.fromPixels(pix2);

+ 190 - 5
h2d/TileGroup.hx

@@ -3,12 +3,28 @@ package h2d;
 import h2d.RenderContext;
 import h2d.impl.BatchDrawState;
 
+/**
+	TileGroup internal class for batched quad geometry rendering.
+**/
+@:dox(hide)
 class TileLayerContent extends h3d.prim.Primitive {
 
 	var tmp : hxd.FloatBuffer;
+	/**
+		Content bounds left edge.
+	**/
 	public var xMin : Float;
+	/**
+		Content bounds top edge.
+	**/
 	public var yMin : Float;
+	/**
+		Content bounds right edge.
+	**/
 	public var xMax : Float;
+	/**
+		Content bounds bottom edge.
+	**/
 	public var yMax : Float;
 	public var useAllocator = false;
 
@@ -19,6 +35,9 @@ class TileLayerContent extends h3d.prim.Primitive {
 		clear();
 	}
 
+	/**
+		Remove all data from Content instance.
+	**/
 	public function clear() {
 		tmp = new hxd.FloatBuffer();
 		if( buffer != null ) {
@@ -41,10 +60,27 @@ class TileLayerContent extends h3d.prim.Primitive {
 		return if( buffer == null ) tmp.length >> 4 else buffer.totalVertices() >> 1;
 	}
 
+	/**
+		Adds tinted Tile at specified position.
+		@param x X position of the tile relative to drawn Object.
+		@param y Y position of the tile relative to drawn Object.
+		@param color An RGBA vector used for tinting.
+		@param t The Tile to draw.
+	**/
 	public inline function addColor( x : Float, y : Float, color : h3d.Vector, t : Tile ) {
 		add(x, y, color.r, color.g, color.b, color.a, t);
 	}
 
+	/**
+		Adds tinted Tile at specified position.
+		@param x X position of the tile relative to drawn Object.
+		@param y Y position of the tile relative to drawn Object.
+		@param r Red tint value (0...1 range)
+		@param g Green tint value (0...1 range)
+		@param b Blue tint value (0...1 range)
+		@param a Alpha of the drawn Tile
+		@param t The Tile to draw.
+	**/
 	public function add( x : Float, y : Float, r : Float, g : Float, b : Float, a : Float, t : Tile ) {
 		var sx = x + t.dx;
 		var sy = y + t.dy;
@@ -93,6 +129,16 @@ class TileLayerContent extends h3d.prim.Primitive {
 		state.add(4);
 	}
 
+	/**
+		Adds tinted Tile at specified position with provided transform.
+		@param x X position of the tile relative to drawn Object.
+		@param y Y position of the tile relative to drawn Object.
+		@param sx X-axis scaling factor of the Tile.
+		@param sy Y-axis scaling factor of the Tile.
+		@param r Rotation (in radians) of the Tile.
+		@param c An RGBA vector used for tinting.
+		@param t The Tile to draw.
+	**/
 	public function addTransform( x : Float, y : Float, sx : Float, sy : Float, r : Float, c : h3d.Vector, t : Tile ) {
 
 		var ca = Math.cos(r), sa = Math.sin(r);
@@ -166,8 +212,12 @@ class TileLayerContent extends h3d.prim.Primitive {
 	}
 
 	/**
+		Intended for internal usage. Adds single vertex to the buffer with no 0 uv.
+
 		Usage warning: When adding geometry trough addPoint, they should be added in groups of 4 that form a quad,
 		and then `updateState(null, quads * 2)` should be called to ensure proper batch rendering.
+
+		Points are added in the following order: top-left, top-right, bottom-left, bottom-right.
 	**/
 	public function addPoint( x : Float, y : Float, color : Int ) {
 		tmp.push(x);
@@ -188,6 +238,14 @@ class TileLayerContent extends h3d.prim.Primitive {
 		tmp.push((c >>> 24) / 255.);
 	}
 
+	/**
+		Adds simple tinted rectangle at specified position. UV covers entire bound texture.
+		@param x X position of the rectangle relative to drawn Object.
+		@param y Y position of the rectangle relative to drawn Object.
+		@param w Width of the rectangle in pixels.
+		@param h Height of the rectangle in pixels.
+		@param color An ARGB color integer used for tinting.
+	**/
 	public inline function rectColor( x : Float, y : Float, w : Float, h : Float, color : Int ) {
 		tmp.push(x);
 		tmp.push(y);
@@ -220,6 +278,17 @@ class TileLayerContent extends h3d.prim.Primitive {
 		state.add(4);
 	}
 
+	/**
+		Adds simple rectangular gradient at specified position. UV covers entire bound texture.
+		@param x X position of the rectangle relative to drawn Object.
+		@param y Y position of the rectangle relative to drawn Object.
+		@param w Width of the rectangle in pixels.
+		@param h Height of the rectangle in pixels.
+		@param ctl Tint color of the top-left corner.
+		@param ctr Tint color of the top-right corner.
+		@param cbl Tint color of the bottom-left corner.
+		@param cbr Tint color of the bottom-right corner.
+	**/
 	public inline function rectGradient( x : Float, y : Float, w : Float, h : Float, ctl : Int, ctr : Int, cbl : Int, cbr : Int ) {
 		tmp.push(x);
 		tmp.push(y);
@@ -239,7 +308,7 @@ class TileLayerContent extends h3d.prim.Primitive {
 		tmp.push(x + w);
 		tmp.push(y + h);
 		tmp.push(1);
-		tmp.push(0);
+		tmp.push(1);
 		insertColor(cbr);
 
 		if( x < xMin ) xMin = x;
@@ -252,6 +321,15 @@ class TileLayerContent extends h3d.prim.Primitive {
 		state.add(4);
 	}
 
+	/**
+		Adds a filled arc at specified position.
+		@param x X position of the arc center.
+		@param y Y position of the arc center.
+		@param ray Radius of the arc.
+		@param c ARGB color of the arc.
+		@param start Starting angle (in radians) of the arc.
+		@param end Ending angle (in radians) of the arc.
+	**/
 	public inline function fillArc( x : Float, y : Float, ray : Float, c : Int, start: Float, end: Float) {
 		if (end <= start) return;
 		var arcLength = end - start;
@@ -289,6 +367,13 @@ class TileLayerContent extends h3d.prim.Primitive {
 		state.add(count + 4);
 	}
 
+	/**
+		Adds a filled circle at specified position.
+		@param x X position of the circle center.
+		@param y Y position of the circle center.
+		@param radius Radius of the circle.
+		@param c ARGB color of the circle.
+	**/
 	public inline function fillCircle( x : Float, y : Float, radius : Float, c : Int) {
 		var nsegments = Math.ceil(radius * 3.14 * 2 / 2);
 		if( nsegments < 3 ) nsegments = 3;
@@ -324,6 +409,14 @@ class TileLayerContent extends h3d.prim.Primitive {
 		state.add(count + 4);
 	}
 
+	/**
+		Adds a circle at specified position.
+		@param x X position of the circle center.
+		@param y Y position of the circle center.
+		@param ray Radius of the circle outer edge.
+		@param size Radius of the circle inner edge.
+		@param c ARGB color of the arc.
+	**/
 	public inline function circle( x : Float, y : Float, ray : Float, size: Float, c : Int) {
 		if (size > ray) return;
 		var nsegments = Math.ceil(ray * 3.14 * 2 / 2);
@@ -356,6 +449,16 @@ class TileLayerContent extends h3d.prim.Primitive {
 		state.add(count);
 	}
 
+	/**
+		Adds a arc at specified position.
+		@param x X position of the arc center.
+		@param y Y position of the arc center.
+		@param ray Radius of the arc outer edge.
+		@param size Radius of the arc inner edge.
+		@param start Starting angle (in radians) of the arc.
+		@param end Ending angle (in radians) of the arc.
+		@param c ARGB color of the arc.
+	**/
 	public inline function arc( x : Float, y : Float, ray : Float, size: Float, start: Float, end: Float, c : Int) {
 		if (size > ray) return;
 		if (end <= start) return;
@@ -421,10 +524,19 @@ class TileLayerContent extends h3d.prim.Primitive {
 		super.dispose();
 	}
 
+	/**
+		Flushes added quads to the rendering buffer.
+		Only flushes if rendering buffer is disposed, and to ensure new data is added, call `dispose()` first.
+	**/
 	public inline function flush() {
 		if( buffer == null || buffer.isDisposed() ) alloc(h3d.Engine.getCurrent());
 	}
 
+	/**
+		Renders the Content quads.
+		@param min Initial triangle offset of buffer to draw.
+		@param len Amount of triangle to draw. (`-1` to render until the end of buffer)
+	**/
 	public inline function doRender(ctx : RenderContext, min, len) {
 		flush();
 		state.drawQuads(ctx, buffer, min, len);
@@ -432,15 +544,40 @@ class TileLayerContent extends h3d.prim.Primitive {
 
 }
 
+/**
+	A static Tile batch renderer.
+
+	TileGroup follows an upload-once policy and does not allow modification of the already added geometry.
+	To add new geometry it's mandatory to call `TileGroup.invalidate`. In case existing geometry has to be modified -
+	entire group have to be cleared with `TileGroup.clear` and repopulated from ground up.
+
+	Usage note: While TileGroup allows for multiple unique textures, each texture swap causes a new drawcall,
+	and due to that it's recommended to minimize the amount of used textures per TileGroup instance,
+	ideally limiting to only one texture.
+**/
 class TileGroup extends Drawable {
 
 	var content : TileLayerContent;
 	var curColor : h3d.Vector;
 
+	/**
+		The reference tile used as a Texture source to draw.
+	**/
 	public var tile : Tile;
+	/**
+		If set, only tiles indexed above or equal to `rangeMin` will be drawn.
+	**/
 	public var rangeMin : Int;
+	/**
+		If set, only tiles indexed below `rangeMax` will be drawn.
+	**/
 	public var rangeMax : Int;
 
+	/**
+		Create new TileGroup instance using Texture based on provided Tile.
+		@param t The Tile which is used as a source for a Texture to be rendered.
+		@param parent An optional parent `h2d.Object` instance to which TileGroup adds itself if set.
+	**/
 	public function new(?t : Tile, ?parent : h2d.Object) {
 		super(parent);
 		tile = t;
@@ -454,20 +591,24 @@ class TileGroup extends Drawable {
 		addBounds(relativeTo, out, content.xMin, content.yMin, content.xMax - content.xMin, content.yMax - content.yMin);
 	}
 
+	/**
+		Clears all TileGroup contents and disposes allocated GPU memory.
+	**/
 	public function clear() : Void {
 		content.clear();
 	}
 
 	/**
-		If you want to add tiles after the GPU memory has been allocated (when the tilegroup with sync/displayed),
-		make sure to call invalidate() first to force a refresh of your data.
+		When new data is added, it's not automatically flushed to the GPU memory if it was already allocated
+		(when TileGroup is either rendered or received `Object.sync` call),
+		in which case call `invalidate()` to force a refresh of the GPU data.
 	**/
 	public function invalidate() : Void {
 		content.dispose();
 	}
 
 	/**
-		Returns the number of tiles added to the group
+		Returns the number of tiles added to the group.
 	**/
 	public function count() : Int {
 		return content.triCount() >> 1;
@@ -478,6 +619,9 @@ class TileGroup extends Drawable {
 		super.onRemove();
 	}
 
+	/**
+		Sets the default tinting color when adding new Tiles.
+	**/
 	public function setDefaultColor( rgb : Int, alpha = 1.0 ) {
 		curColor.x = ((rgb >> 16) & 0xFF) / 255;
 		curColor.y = ((rgb >> 8) & 0xFF) / 255;
@@ -485,18 +629,50 @@ class TileGroup extends Drawable {
 		curColor.w = alpha;
 	}
 
+	/**
+		Adds a Tile at specified position. Tile is tinted by the current default color.
+		@param x X position of the tile relative to the TileGroup.
+		@param y Y position of the tile relative to the TileGroup.
+		@param t The Tile to draw.
+	**/
 	public inline function add(x : Float, y : Float, t : h2d.Tile) {
 		content.add(x, y, curColor.x, curColor.y, curColor.z, curColor.w, t);
 	}
 
+	/**
+		Adds a tinted Tile at specified position.
+		@param x X position of the tile relative to the TileGroup.
+		@param y Y position of the tile relative to the TileGroup.
+		@param r Red tint value (0...1 range).
+		@param g Green tint value (0...1 range).
+		@param b Blue tint value (0...1 range).
+		@param a Alpha of the drawn Tile.
+		@param t The Tile to draw.
+	**/
 	public inline function addColor( x : Float, y : Float, r : Float, g : Float, b : Float, a : Float, t : Tile) {
 		content.add(x, y, r, g, b, a, t);
 	}
 
+	/**
+		Adds a Tile at specified position. Tile is tinted by the current default color RGB value and provided alpha.
+		@param x X position of the tile relative to the TileGroup.
+		@param y Y position of the tile relative to the TileGroup.
+		@param a Alpha of the drawn Tile.
+		@param t The Tile to draw.
+	**/
 	public inline function addAlpha(x : Float, y : Float, a : Float, t : h2d.Tile) {
 		content.add(x, y, curColor.x, curColor.y, curColor.z, a, t);
 	}
 
+	/**
+		Adds a Tile at specified position with provided transform. Tile is tinted by the current default color.
+		@param x X position of the tile relative to the TileGroup.
+		@param y Y position of the tile relative to the TileGroup.
+		@param sx X-axis scaling factor of the Tile.
+		@param sy Y-axis scaling factor of the Tile.
+		@param r Rotation (in radians) of the Tile.
+		@param t The Tile to draw.
+	**/
 	public inline function addTransform(x : Float, y : Float, sx : Float, sy : Float, r : Float, t : Tile) {
 		content.addTransform(x, y, sx, sy, r, curColor, t);
 	}
@@ -505,7 +681,6 @@ class TileGroup extends Drawable {
 		drawWith(ctx,this);
 	}
 
-
 	override function sync( ctx : RenderContext ) {
 		super.sync(ctx);
 		// On some mobile GPU, uploading while rendering does create a lot of stall.
@@ -514,7 +689,17 @@ class TileGroup extends Drawable {
 		content.flush();
 	}
 
+	/**
+		Render the TileGroup contents using the referenced Drawable position, shaders and other parameters.
+
+		An advanced rendering approach, that allows to render TileGroup contents relative to another object
+		and used primarily by `Text` and `HtmlText`.
+
+		@param ctx The render context with which to render the TileGroup.
+		@param obj The Drawable which will be used as a source of the rendering parameters.
+	**/
 	@:allow(h2d)
+	@:dox(show)
 	function drawWith( ctx:RenderContext, obj : Drawable ) {
 		var max = content.triCount();
 		if( max == 0 )

+ 47 - 0
h2d/Video.hx

@@ -23,6 +23,13 @@ private abstract VideoImpl(hl.Abstract<"hl_video">) {
 }
 #end
 
+/**
+	A video file playback Drawable. Due to platform specifics, each target have their own limitations.
+
+	* <span class="label">Hashlink</span>: Playback ability depends on `video` library.
+		At the time of HL 1.11 it's not bundled and have to be [compiled manually](https://github.com/HaxeFoundation/hashlink/tree/master/libs/video) with FFMPEG.
+	* <span class="label">JavaScript</span>: HTML Video element will be used. Playback is restricted by content-security policy and browser decoder capabilities.
+**/
 class Video extends Drawable {
 
 	#if hl
@@ -42,24 +49,50 @@ class Video extends Drawable {
 	var frameReady : Bool;
 	var loopVideo : Bool;
 
+	/**
+		Video width. Value is undefined until video is ready to play.
+	**/
 	public var videoWidth(default, null) : Int;
+	/**
+		Video height. Value is undefined until video is ready to play.
+	**/
 	public var videoHeight(default, null) : Int;
+	/**
+		Tells if video currently playing.
+	**/
 	public var playing(default, null) : Bool;
+	/**
+		Tells current timestamp of the video.
+	**/
 	public var time(get, null) : Float;
+	/**
+		When enabled, video will loop indefinitely.
+	**/
 	public var loop(get, set) : Bool;
 
+	/**
+		Create a new Video instance.
+		@param parent An optional parent `h2d.Object` instance to which Video adds itself if set.
+	**/
 	public function new(?parent) {
 		super(parent);
 		blendMode = None;
 		smooth = true;
 	}
 
+	/**
+		Sent when there is an error with the decoding or playback of the video.
+	**/
 	public dynamic function onError( msg : String ) {
 	}
 
+	/**
+		Sent when video playback is finished.
+	**/
 	public dynamic function onEnd() {
 	}
 
+	@:dox(hide) @:noCompletion
 	public function get_time() {
 		#if js
 		return playing ? v.currentTime : 0;
@@ -68,10 +101,12 @@ class Video extends Drawable {
 		#end
 	}
 	
+	@:dox(hide) @:noCompletion
 	public inline function get_loop() {
 		return loopVideo;
 	}
 	
+	@:dox(hide) @:noCompletion
 	public function set_loop(value : Bool) : Bool {
 		#if js
 		return v.loop = loopVideo = value;
@@ -80,6 +115,9 @@ class Video extends Drawable {
 		#end
 	}
 
+	/**
+		Disposes of the currently playing Video and frees GPU memory.
+	**/
 	public function dispose() {
 		#if hl
 		if( v != null ) {
@@ -107,6 +145,15 @@ class Video extends Drawable {
 		frameReady = false;
 	}
 
+	/**
+		Loads and starts the video playback by specified `path` and calls `onReady` when playback becomes possible.
+
+		* <span class="label">Hashlink</span>: Playback being immediately after `load`, unless video was not being able to initialize.
+		* <span class="label">JavaScript</span>: There won't be any video output until video is properly buffered enough data by the browser, in which case `onReady` is called.
+
+		@param path The video path. Have to be valid file-system path for HL or valid URL (full or relative) for JS.
+		@param onReady An optional callback signalling that video is initialized and began the video playback.
+	**/
 	public function load( path : String, ?onReady : Void -> Void ) {
 		dispose();
 

+ 20 - 3
h2d/ZGroup.hx

@@ -1,5 +1,4 @@
 package h2d;
-import haxe.ds.Vector;
 
 @:access(h2d.RenderContext)
 private class State {
@@ -35,6 +34,7 @@ private class DepthEntry {
 	public function new() { }
 }
 
+@:dox(hide)
 class DepthMap {
 	var map      : Map<Object, DepthEntry>;
 	var curIndex : Int;
@@ -116,6 +116,19 @@ class DepthMap {
 	}
 }
 
+/**
+	An advanced double-pass rendering class that utilizes a z-culling on an opaque objects.
+
+	For optimization to work properly, all opaque objects should have `Object.blendMode` set to `None`.
+	
+	Rendering is done in two passes:
+	* An opaque pass only renders objects with `blendeMode = None`, with `RenderContext.front2back` and `RenderContext.killAlpha` enabled.
+	* Transparent pass renders the rest of the objects (which are not marked as opaque) as usual.
+
+	That allows to perform a z-cull depth test on the objects and reduce the overall GPU strain.
+	
+	Additionally, ZGroup places a limitation on filter usage. They are not drawn in opaque pass, which can lead to undefined behavior.
+**/
 @:access(h2d.RenderContext)
 class ZGroup extends Layers
 {
@@ -128,8 +141,12 @@ class ZGroup extends Layers
 	var onEnterFilterCached : Object -> Bool;
 	var onLeaveFilterCached : Object -> Void;
 
-	public function new(?p) {
-		super(p);
+	/**
+		Create a new ZGroup instance/
+		@param parent An optional parent `h2d.Object` instance to which ZGroup adds itself if set.
+	**/
+	public function new(?parent) {
+		super(parent);
 
 		depthMap = new DepthMap();
 

+ 139 - 17
h2d/col/Bounds.hx

@@ -1,38 +1,74 @@
 package h2d.col;
 import hxd.Math;
+/**
+	A 2D bounding box often used for determining Object bounding area.
 
+	Bounds holds min/max coordinates of bounding box instead of it's position and size.
+	@see `Object.getBounds`
+	@see `Object.getSize`
+**/
 class Bounds {
 
+	/** X-axis left-most bounding box point. **/
 	public var xMin : Float;
+	/** Y-axis top-most bounding box point. **/
 	public var yMin : Float;
-
+	
+	/** X-axis right-most bounding box point. **/
 	public var xMax : Float;
+	/** Y-axis bottom-most bounding box point. **/
 	public var yMax : Float;
 
-
+	/**
+		X-axis position of the bounding box top-left corner. Modifying it alters both `Bounds.xMin` and `Bounds.xMax`.
+	**/
 	public var x(get, set) : Float;
+	/**
+		Y-axis position of the bounding box top-left corner. Modifying it alters both `Bounds.yMin` and `Bounds.yMax`.
+	**/
 	public var y(get, set) : Float;
+	/**
+		Width of the bounding box. Equivalent of `xMax - xMin`.
+	**/
 	public var width(get, set) : Float;
+	/**
+		Height of the bounding box. Equivalent of `yMax - yMin`.
+	**/
 	public var height(get, set) : Float;
 
+	/**
+		Create new empty Bounds instance.
+	**/
 	public inline function new() {
 		empty();
 	}
 
-	public inline function toIBounds( scale = 1. ) {
+	/**
+		Converts bounding box to integer bounding box scaled by provided scalar `scale` (rounded down for `min` and up for `max`).
+	**/
+	public inline function toIBounds( scale = 1. ) : IBounds {
 		var ix = Math.floor(x * scale);
 		var iy = Math.floor(y * scale);
 		return IBounds.fromValues(ix, iy, Math.ceil(xMax * scale) - ix, Math.ceil(yMax * scale) - iy);
 	}
 
-	public inline function intersects( b : Bounds ) {
+	/**
+		Tests if this Bounds instance intersects with given `b` Bounds.
+	**/
+	public inline function intersects( b : Bounds ) : Bool {
 		return !(xMin > b.xMax || yMin > b.yMax || xMax < b.xMin || yMax < b.yMin);
 	}
 
-	public inline function contains( p : Point ) {
+	/**
+		Tests if the Point `p` is inside the bounding box.
+	**/
+	public inline function contains( p : Point ) : Bool {
 		return p.x >= xMin && p.x < xMax && p.y >= yMin && p.y < yMax;
 	}
 
+	/**
+		Adds Bounds `b` to the Bounds, expanding min/max when necessary.
+	**/
 	public inline function addBounds( b : Bounds ) {
 		if( b.xMin < xMin ) xMin = b.xMin;
 		if( b.xMax > xMax ) xMax = b.xMax;
@@ -40,6 +76,9 @@ class Bounds {
 		if( b.yMax > yMax ) yMax = b.yMax;
 	}
 
+	/**
+		Adds the Point `p` to the bounding box, expanding min/max when necessary.
+	**/
 	public inline function addPoint( p : Point ) {
 		if( p.x < xMin ) xMin = p.x;
 		if( p.x > xMax ) xMax = p.x;
@@ -47,6 +86,9 @@ class Bounds {
 		if( p.y > yMax ) yMax = p.y;
 	}
 
+	/**
+		Adds the `x` and `y` position to the bounding box, expanding min/max when necessary.
+	**/
 	public inline function addPos( x : Float, y : Float ) {
 		if( x < xMin ) xMin = x;
 		if( x > xMax ) xMax = x;
@@ -54,23 +96,41 @@ class Bounds {
 		if( y > yMax ) yMax = y;
 	}
 
-	public inline function set(x, y, width, height) {
+	/**
+		Sets the bounding box from the given rectangle.
+		@param x Rectangle top-left corner horizontal position.
+		@param y Rectangle top-left corner vertical position.
+		@param width Rectangle width.
+		@param height Rectangle height.
+	**/
+	public inline function set( x : Float, y : Float, width : Float, height : Float ) {
 		this.xMin = x;
 		this.yMin = y;
 		this.xMax = x + width;
 		this.yMax = y + height;
 	}
 
+	/**
+		Sets the `Bounds.xMin` and `Bounds.yMin` to values in the given Point `p`.
+	**/
 	public inline function setMin( p : Point ) {
 		xMin = p.x;
 		yMin = p.y;
 	}
 
+	/**
+		Sets the `Bounds.xMax` and `Bounds.yMax` to values in the given Point `p`.
+	**/
 	public inline function setMax( p : Point ) {
 		xMax = p.x;
 		yMax = p.y;
 	}
 
+	/**
+		Sets the bounding box min/max values to a result of the intersection between this Bounds and the given Bounds `b`.
+
+		See `Bounds.intersection` to get new instance of Bounds as intersection result.
+	**/
 	public inline function doIntersect( b : Bounds ) {
 		xMin = Math.max(xMin, b.xMin);
 		yMin = Math.max(yMin, b.yMin);
@@ -78,6 +138,11 @@ class Bounds {
 		yMax = Math.min(yMax, b.yMax);
 	}
 
+	/**
+		Sets this bounding box min/max values to a result of combining this Bounds and the given Bounds `b`.
+		
+		Equivalent of `Bounds.addBounds`.
+	**/
 	public inline function doUnion( b : Bounds ) {
 		xMin = Math.min(xMin, b.xMin);
 		yMin = Math.min(yMin, b.yMin);
@@ -85,7 +150,10 @@ class Bounds {
 		yMax = Math.max(yMax, b.yMax);
 	}
 
-	public function intersection( b : Bounds ) {
+	/**
+		Returns a new Bounds instance containing intersection results of this Bounds and the given Bounds `b`.
+	**/
+	public function intersection( b : Bounds ) : Bounds {
 		var i = new Bounds();
 		i.xMin = Math.max(xMin, b.xMin);
 		i.yMin = Math.max(yMin, b.yMin);
@@ -96,7 +164,10 @@ class Bounds {
 		return i;
 	}
 
-	public function union( b : Bounds ) {
+	/**
+		Returns a new Bounds instance containing union of this Bounds and the given Bounds `b`.
+	**/
+	public function union( b : Bounds ) : Bounds {
 		var i = new Bounds();
 		i.xMin = Math.min(xMin, b.xMin);
 		i.yMin = Math.min(yMin, b.yMin);
@@ -105,6 +176,9 @@ class Bounds {
 		return i;
 	}
 
+	/**
+		Copies the min/max values from the given Bounds `b` to this Bounds.
+	**/
 	public function load( b : Bounds ) {
 		xMin = b.xMin;
 		yMin = b.yMin;
@@ -112,6 +186,9 @@ class Bounds {
 		yMax = b.yMax;
 	}
 
+	/**
+		Scales the min/max values relative to `0,0` coordinate.
+	**/
 	public inline function scalePivot( v : Float ) {
 		xMin *= v;
 		yMin *= v;
@@ -119,6 +196,9 @@ class Bounds {
 		yMax *= v;
 	}
 
+	/**
+		Scales the min/max values relative the current bounding box center point.
+	**/
 	public function scaleCenter( v : Float ) {
 		var dx = (xMax - xMin) * 0.5 * v;
 		var dy = (yMax - yMin) * 0.5 * v;
@@ -130,6 +210,9 @@ class Bounds {
 		yMax = my + dy;
 	}
 
+	/**
+		Rotates the bounding box around `0,0` point by given `angle` and sets min/max to the new rotated boundaries.
+	**/
 	public function rotate( angle : Float ) {
 		var cos = Math.cos(angle);
 		var sin = Math.sin(angle);
@@ -141,6 +224,9 @@ class Bounds {
 		addPos(x1 * cos - y1 * sin, x1 * sin + y1 * cos);
 	}
 
+	/**
+		Moves entire bounding box by `dx, dy`.
+	**/
 	public inline function offset( dx : Float, dy : Float ) {
 		xMin += dx;
 		xMax += dx;
@@ -148,26 +234,45 @@ class Bounds {
 		yMax += dy;
 	}
 
-	public inline function getMin() {
+	/**
+		Returns a new Point containing `Bounds.xMin` and `Bounds.yMin`.
+	**/
+	public inline function getMin() : Point {
 		return new Point(xMin, yMin);
 	}
 
-	public inline function getCenter() {
+	/**
+		Returns a new Point containing the center coordinate of the bounding box.
+	**/
+	public inline function getCenter() : Point {
 		return new Point((xMin + xMax) * 0.5, (yMin + yMax) * 0.5);
 	}
 
-	public inline function getSize() {
+	/**
+		Returns a new Point containing size of the bounding box.
+	**/
+	public inline function getSize() : Point {
 		return new Point(xMax - xMin, yMax - yMin);
 	}
 
-	public inline function getMax() {
+	/**
+		Returns a new Point containing `Bounds.xMax` and `Bounds.yMax`.
+	**/
+	public inline function getMax() : Point {
 		return new Point(xMax, yMax);
 	}
 
-	public inline function isEmpty() {
+	/**
+		Tests if bounding box is empty.
+		Bounds are considered empty when either `Bounds.xMax` is less than or equals to `Bounds.xMin` or `Bounds.yMax` is less than or equals to `Bounds.yMin`.
+	**/
+	public inline function isEmpty() : Bool {
 		return xMax <= xMin || yMax <= yMin;
 	}
 
+	/**
+		Clears bounding box into an empty state.
+	**/
 	public inline function empty() {
 		xMin = 1e20;
 		yMin = 1e20;
@@ -175,6 +280,9 @@ class Bounds {
 		yMax = -1e20;
 	}
 
+	/**
+		Sets the bounding box to cover maximum area (`-1e20...1e20`).
+	**/
 	public inline function all() {
 		xMin = -1e20;
 		yMin = -1e20;
@@ -182,7 +290,10 @@ class Bounds {
 		yMax = 1e20;
 	}
 
-	public inline function clone() {
+	/**
+		Returns new copy of this Bounds instance.
+	**/
+	public inline function clone() : Bounds {
 		var b = new Bounds();
 		b.xMin = xMin;
 		b.yMin = yMin;
@@ -227,11 +338,19 @@ class Bounds {
 		return h;
 	}
 
-	public function toString() {
+	@:dox(hide)
+	public function toString() : String {
 		return "{" + getMin() + "," + getSize() + "}";
 	}
 
-	public static inline function fromValues( x0 : Float, y0 : Float, width : Float, height : Float ) {
+	/**
+		Returns a new Bounds instance from given rectangle.
+		@param x Rectangle horizontal position.
+		@param y Rectangle vertical position.
+		@param width Rectangle width.
+		@param height Rectangle height.
+	**/
+	public static inline function fromValues( x0 : Float, y0 : Float, width : Float, height : Float ) : Bounds {
 		var b = new Bounds();
 		b.xMin = x0;
 		b.yMin = y0;
@@ -240,7 +359,10 @@ class Bounds {
 		return b;
 	}
 
-	public static inline function fromPoints( min : Point, max : Point ) {
+	/**
+		Returns a new Bounds instance from given `min`/`max` Points.
+	**/
+	public static inline function fromPoints( min : Point, max : Point ) : Bounds {
 		var b = new Bounds();
 		b.setMin(min);
 		b.setMax(max);

+ 45 - 5
h2d/col/Circle.hx

@@ -1,38 +1,68 @@
 package h2d.col;
 import hxd.Math;
 
+/**
+	The circular hitbox implementation of a 2D Collider.
+**/
 class Circle implements Collider {
 
+	/**
+		Horizontal position of the Circle center.
+	**/
 	public var x : Float;
+	/**
+		Vertical position of the Circle center.
+	**/
 	public var y : Float;
+	/**
+		Radius of the circle.
+	**/
 	public var ray : Float;
 
+	/**
+		Create new Circle collider.
+		@param x X position of the Circle center.
+		@param y Y position of the Circle center.
+		@param ray Radius of the circle.
+	**/
 	public inline function new( x : Float, y : Float, ray : Float ) {
 		this.x = x;
 		this.y = y;
 		this.ray = ray;
 	}
 
-	public inline function distanceSq( p : Point ) {
+	/**
+		Returns a squared distance between the Circle center and the given Point `p`.
+	**/
+	public inline function distanceSq( p : Point ) : Float {
 		var dx = p.x - x;
 		var dy = p.y - y;
 		var d = dx * dx + dy * dy - ray * ray;
 		return d < 0 ? 0 : d;
 	}
 
-	public inline function side( p : Point ) {
+	/**
+		Returns a squared distance between the Circle border and the given Point `p`.
+	**/
+	public inline function side( p : Point ) : Float {
 		var dx = p.x - x;
 		var dy = p.y - y;
 		return ray * ray - (dx * dx + dy * dy);
 	}
 
-	public inline function collideCircle( c : Circle ) {
+	/**
+		Tests if this Circle collides with the given Circle `c`.
+	**/
+	public inline function collideCircle( c : Circle ) : Bool {
 		var dx = x - c.x;
 		var dy = y - c.y;
 		return dx * dx + dy * dy < (ray + c.ray) * (ray + c.ray);
 	}
 
-	public inline function collideBounds( b : Bounds ) {
+	/**
+		Test if this Circle collides with the given Bounds `b`.
+	**/
+	public inline function collideBounds( b : Bounds ) : Bool {
 		if( x < b.xMin - ray ) return false;
 		if( x > b.xMax + ray ) return false;
 		if( y < b.yMin - ray ) return false;
@@ -44,7 +74,13 @@ class Circle implements Collider {
 		return true;
 	}
 
-	public inline function lineIntersect(p1 : h2d.col.Point, p2:h2d.col.Point) {
+	/**
+		Tests if this Circle intersects with a line segment from Point `p1` to Point `p2`.
+		@returns An array of Points with intersection coordinates.
+		Contains 1 Point if line intersects only once or 2 points if line enters and exits the circle.
+		If no intersection is found, returns `null`.
+	**/
+	public inline function lineIntersect(p1 : h2d.col.Point, p2:h2d.col.Point) : Array<Point> {
 		var dx = p2.x - p1.x;
 		var dy = p2.y - p1.y;
 		var a = dx * dx + dy * dy;
@@ -64,10 +100,14 @@ class Circle implements Collider {
 		return [new h2d.col.Point(p1.x + t1 * dx, p1.y + t1 * dy), new h2d.col.Point(p1.x + t2 * dx, p1.y + t2 * dy)];
 	}
 
+	@:dox(hide)
 	public function toString() {
 		return '{${Math.fmt(x)},${Math.fmt(y)},${Math.fmt(ray)}}';
 	}
 
+	/**
+		Tests if Point `p` is inside this Circle.
+	**/
 	public function contains( p : Point ) : Bool {
 		return distanceSq(p) == 0;
 	}

+ 6 - 0
h2d/col/Collider.hx

@@ -1,7 +1,13 @@
 package h2d.col;
 
+/**
+	A common interface for 2D Shapes to hit-test again the mouse or a specific point in space.
+**/
 interface Collider /* extends hxd.impl.Serializable.StructSerializable */ {
 
+	/**
+		Tests if Point `p` is inside the Collider.
+	**/
 	public function contains( p : Point ) : Bool;
 
 }

Failā izmaiņas netiks attēlotas, jo tās ir par lielu
+ 0 - 0
h2d/col/Delaunay.hx


+ 120 - 11
h2d/col/IBounds.hx

@@ -1,36 +1,71 @@
 package h2d.col;
 import hxd.Math;
 
+/**
+	An integer-based bounding box.
+	@see `h2d.col.Bounds`
+**/
 class IBounds {
 
+	/** X-axis left-most bounding box point. **/
 	public var xMin : Int;
+	/** Y-axis top-most bounding box point. **/
 	public var yMin : Int;
 
+	/** X-axis right-most bounds box point. **/
 	public var xMax : Int;
+	/** Y-axis bottom-most bounding box point. **/
 	public var yMax : Int;
 
 
+	/**
+		X-axis position of the bounding-box top-left corner. Modifying it alters both `xMin` and `xMax`.
+	**/
 	public var x(get, set) : Int;
+	/**
+		Y-axis position of the bounding-box top-left corner. Modifying it alters both `xMin` and `xMax`.
+	**/
 	public var y(get, set) : Int;
+	/**
+		Width of the bounding box. Equivalent of `xMax - xMin`.
+	**/
 	public var width(get, set) : Int;
+	/**
+		Height of the bounding box. Equivalent of `yMax - yMin`.
+	**/
 	public var height(get, set) : Int;
 
+	/**
+		Create new empty IBounds instance.
+	**/
 	public inline function new() {
 		empty();
 	}
 
-	public inline function toBounds( scale = 1. ) {
+	/**
+		Converts `IBounds` to regular `Bounds` scaled by provided scalar `scale`.
+	**/
+	public inline function toBounds( scale = 1. ) : Bounds {
 		return Bounds.fromValues(x * scale, y * scale, width * scale, height * scale);
 	}
 
-	public inline function intersects( b : IBounds ) {
+	/**
+		Tests if this IBounds instances intersects given `b` IBounds.
+	**/
+	public inline function intersects( b : IBounds ) : Bool {
 		return !(xMin > b.xMax || yMin > b.yMax || xMax < b.xMin || yMax < b.yMin);
 	}
 
-	public inline function contains( p : IPoint ) {
+	/**
+		Tests if IPoint `p` is inside the IBounds.
+	**/
+	public inline function contains( p : IPoint ) : Bool {
 		return p.x >= xMin && p.x < xMax && p.y >= yMin && p.y < yMax;
 	}
 
+	/**
+		Adds IBounds `b` to the IBounds, expanding min/max when necessary.
+	**/
 	public inline function addBounds( b : IBounds ) {
 		if( b.xMin < xMin ) xMin = b.xMin;
 		if( b.xMax > xMax ) xMax = b.xMax;
@@ -38,6 +73,9 @@ class IBounds {
 		if( b.yMax > yMax ) yMax = b.yMax;
 	}
 
+	/**
+		Adds IPoint `p` to the IBounds, expanding min/max when necessary.
+	**/
 	public inline function addPoint( p : IPoint ) {
 		if( p.x < xMin ) xMin = p.x;
 		if( p.x > xMax ) xMax = p.x;
@@ -45,6 +83,9 @@ class IBounds {
 		if( p.y > yMax ) yMax = p.y;
 	}
 
+	/**
+		Adds position `x` and `y` to the IBounds, expanding min/max when necessary.
+	**/
 	public inline function addPos( x : Int, y : Int ) {
 		if( x < xMin ) xMin = x;
 		if( x > xMax ) xMax = x;
@@ -52,23 +93,40 @@ class IBounds {
 		if( y > yMax ) yMax = y;
 	}
 
-	public inline function set(x, y, width, height) {
+	/**
+		Sets bounds from given rectangle.
+		@param x Rectangle horizontal position.
+		@param y Rectangle vertical position.
+		@param width Rectangle width.
+		@param height Rectangle height.
+	**/
+	public inline function set(x : Int, y : Int, width : Int, height : Int) {
 		this.xMin = x;
 		this.yMin = y;
 		this.xMax = x + width;
 		this.yMax = y + height;
 	}
 
+	/**
+		Sets `xMin` and `yMin` to values in given IPoint `p`.
+	**/
 	public inline function setMin( p : IPoint ) {
 		xMin = p.x;
 		yMin = p.y;
 	}
 
+	/**
+		Sets `xMax` and `yMax` to values in given IPoint `p`.
+	**/
 	public inline function setMax( p : IPoint ) {
 		xMax = p.x;
 		yMax = p.y;
 	}
 
+	/**
+		Sets this IBounds min/max values to a result of intersection between this IBounds and given IBounds `b`.
+		See `intersection` to get new instance of IBounds as intersection result.
+	**/
 	public inline function doIntersect( b : IBounds ) {
 		xMin = Math.imax(xMin, b.xMin);
 		yMin = Math.imax(yMin, b.yMin);
@@ -76,6 +134,9 @@ class IBounds {
 		yMax = Math.imin(yMax, b.yMax);
 	}
 
+	/**
+		Sets this IBounds min/max values to a result of combining this IBounds and given IBounds `b`. Equivalent of `addBounds`.
+	**/
 	public inline function doUnion( b : IBounds ) {
 		xMin = Math.imin(xMin, b.xMin);
 		yMin = Math.imin(yMin, b.yMin);
@@ -83,6 +144,9 @@ class IBounds {
 		yMax = Math.imax(yMax, b.yMax);
 	}
 
+	/**
+		Returns new Bounds instance containing intersection results of this IBounds and given IBounds `b`.
+	**/
 	public function intersection( b : IBounds ) : IBounds {
 		var i = new IBounds();
 		i.xMin = Math.imax(xMin, b.xMin);
@@ -94,6 +158,9 @@ class IBounds {
 		return i;
 	}
 
+	/**
+		Returns new Bounds instance containing union of this IBounds and given IBounds `b`.
+	**/
 	public function union( b : IBounds ) : IBounds {
 		var i = new IBounds();
 		i.xMin = Math.imin(xMin, b.xMin);
@@ -103,6 +170,9 @@ class IBounds {
 		return i;
 	}
 
+	/**
+		Copies min/max values from given IBounds `b` to this IBounds.
+	**/
 	public function load( b : IBounds ) {
 		xMin = b.xMin;
 		yMin = b.yMin;
@@ -110,6 +180,9 @@ class IBounds {
 		yMax = b.yMax;
 	}
 
+	/**
+		Moves entire bounding box by `dx,dy`.
+	**/
 	public inline function offset( dx : Int, dy : Int ) {
 		xMin += dx;
 		xMax += dx;
@@ -117,26 +190,45 @@ class IBounds {
 		yMax += dy;
 	}
 
-	public inline function getMin() {
+	/**
+		Returns a new IPoint containing `xMin` and `yMin`.
+	**/
+	public inline function getMin() : IPoint {
 		return new IPoint(xMin, yMin);
 	}
 
-	public inline function getCenter() {
+	/**
+		Returns a new IPoint containing center coordinate of the IBounds.
+	**/
+	public inline function getCenter() : IPoint {
 		return new IPoint((xMin + xMax) >> 1, (yMin + yMax) >> 1);
 	}
 
-	public inline function getSize() {
+	/**
+		Returns a new IPoint containing size of the IBounds.
+	**/
+	public inline function getSize() : IPoint {
 		return new IPoint(xMax - xMin, yMax - yMin);
 	}
 
-	public inline function getMax() {
+	/**
+		Returns a new IPoint containing `xMax` and `yMax`.
+	**/
+	public inline function getMax() : IPoint {
 		return new IPoint(xMax, yMax);
 	}
 
-	public inline function isEmpty() {
+	/**
+		Tests if bounding box is empty.
+		IBounds are considered empty when either `xMax` is less than or equals to `xMin` or `yMax` is less than or equals to `yMin`.
+	**/
+	public inline function isEmpty() : Bool {
 		return xMax <= xMin || yMax <= yMin;
 	}
 
+	/**
+		Clears IBounds into an empty state.
+	**/
 	public inline function empty() {
 		xMin = 0x7FFFFFFF;
 		yMin = 0x7FFFFFFF;
@@ -144,6 +236,9 @@ class IBounds {
 		yMax = -2147483648;
 	}
 
+	/**
+		Sets bounds to cover maximum area (`-2147483648...0x7FFFFFFF`).
+	**/
 	public inline function all() {
 		xMin = -2147483648;
 		yMin = -2147483648;
@@ -151,6 +246,9 @@ class IBounds {
 		yMax = 0x7FFFFFFF;
 	}
 
+	/**
+		Returns new copy of this IBounds instance.
+	**/
 	public inline function clone() {
 		var b = new IBounds();
 		b.xMin = xMin;
@@ -196,11 +294,19 @@ class IBounds {
 		return h;
 	}
 
+	@:dox(hide)
 	public function toString() {
 		return "{" + getMin() + "," + getSize() + "}";
 	}
 
-	public static inline function fromValues( x0 : Int, y0 : Int, width : Int, height : Int ) {
+	/**
+		Returns a new IBounds instance from given rectangle.
+		@param x Rectangle horizontal position.
+		@param y Rectangle vertical position.
+		@param width Rectangle width.
+		@param height Rectangle height.
+	**/
+	public static inline function fromValues( x0 : Int, y0 : Int, width : Int, height : Int ) : IBounds {
 		var b = new IBounds();
 		b.xMin = x0;
 		b.yMin = y0;
@@ -209,7 +315,10 @@ class IBounds {
 		return b;
 	}
 
-	public static inline function fromPoints( min : IPoint, max : IPoint ) {
+	/**
+		Returns a new IBounds instance from given min/max IPoints.
+	**/
+	public static inline function fromPoints( min : IPoint, max : IPoint ) : IBounds {
 		var b = new IBounds();
 		b.setMin(min);
 		b.setMax(max);

+ 68 - 7
h2d/col/IPoint.hx

@@ -1,85 +1,146 @@
 package h2d.col;
 import hxd.Math;
 
+/**
+	An integer-based point.
+	@see `h2d.col.Point`
+**/
 class IPoint #if apicheck implements h2d.impl.PointApi.IPointApi<IPoint> #end {
 
+	/**
+		Horizontal position of the point.
+	**/
 	public var x : Int;
+	/**
+		Vertical position of the point.
+	**/
 	public var y : Int;
 
 	// -- gen api
 
+	/**
+		Create a new integer Point instance.
+		@param x Horizontal position of the point.
+		@param y Vertical position of the point.
+	**/
 	public inline function new(x = 0, y = 0) {
 		this.x = x;
 		this.y = y;
 	}
 
+	/**
+		Copy the position from the give point `p` into this IPoint.
+	**/
 	public inline function load( p : IPoint ) {
 		this.x = p.x;
 		this.y = p.y;
 	}
 
+	/**
+		Multiplies the position of this IPoint by a given scalar `v`. Modifies this instance.
+	**/
 	public inline function scale( v : Int ) {
 		x *= v;
 		y *= v;
 	}
 
+	/**
+		Returns a new IPoint with the position of this IPoint multiplied by a given scalar `v`.
+	**/
 	public inline function multiply( v : Int ) {
 		return new IPoint(x * v, y * v);
 	}
 
-	public inline function distanceSq( p : IPoint ) {
+	/**
+		Returns squared distance between this IPoint and given IPoint `p`.
+	**/
+	public inline function distanceSq( p : IPoint ) : Int {
 		var dx = x - p.x;
 		var dy = y - p.y;
 		return dx * dx + dy * dy;
 	}
 
-	public inline function distance( p : IPoint ) {
+	/**
+		Returns a distance between this IPoint and given IPoint `p`.
+	**/
+	public inline function distance( p : IPoint ) : Float {
 		return Math.sqrt(distanceSq(p));
 	}
 
-	public function toString() {
+	@:dox(hide)
+	public function toString() : String {
 		return "{" + x + "," + y + "}";
 	}
 
+	/**
+		Subtracts IPoint `p` from this IPoint and returns new Point with the result.
+	**/
 	public inline function sub( p : IPoint ) : IPoint {
 		return new IPoint(x - p.x, y - p.y);
 	}
 
+	/**
+		Adds IPoint `p` to this IPoint and returns new Point with the result.
+	**/
 	public inline function add( p : IPoint ) : IPoint {
 		return new IPoint(x + p.x, y + p.y);
 	}
 
+	/**
+		Tests if this IPoint position equals to `other` IPoint position.
+	**/
 	public inline function equals( other : IPoint ) : Bool {
 		return x == other.x && y == other.y;
 	}
 
-	public inline function dot( p : IPoint ) {
+	/**
+		Returns a dot product between this IPoint and given IPoint `p`.
+	**/
+	public inline function dot( p : IPoint ) : Int {
 		return x * p.x + y * p.y;
 	}
 
-	public inline function lengthSq() {
+	/**
+		Returns squared length of this IPoint.
+	**/
+	public inline function lengthSq() : Int {
 		return x * x + y * y;
 	}
 
-	public inline function length() {
+	/**
+		Returns length (distance to `0,0`) of this IPoint.
+	**/
+	public inline function length() : Float {
 		return Math.sqrt(lengthSq());
 	}
 
+	/**
+		Sets the IPoint `x, y` with given values.
+	**/
 	public inline function set(x=0,y=0) {
 		this.x = x;
 		this.y = y;
 	}
 
-	public inline function clone() {
+	/**
+		Returns a copy of this IPoint.
+	**/
+	public inline function clone() : IPoint {
 		return new IPoint(x, y);
 	}
 
+	/**
+		Returns a cross product between this IPoint and a given IPoint `p`.
+	**/
 	public inline function cross( p : IPoint ) {
 		return x * p.y - y * p.x;
 	}
 
 	// -- end gen api
 
+	/**
+		Converts this IPoint to floating point-based `Point` scaled by provided scalar `scale`.
+	**/
 	public inline function toPoint( scale = 1. ) {
 		return new Point(x * scale, y * scale);
 	}

+ 69 - 4
h2d/col/IPolygon.hx

@@ -1,39 +1,67 @@
 package h2d.col;
 import hxd.Math;
 
+/**
+	The type of the edges when offsetting polygon with `IPolygon.offset`.
+**/
 enum OffsetKind {
 	Square;
 	Miter;
 	Round( arc : Float );
 }
 
+/**
+	An abstract around an Array of `IPoint`s that define a polygonal shape that can be collision-tested against.
+	@see `h2d.col.Polygon`
+**/
 @:forward(push,remove)
 abstract IPolygon(Array<IPoint>) from Array<IPoint> to Array<IPoint> {
-
+	/**
+		The underlying Array of vertices.
+	**/
 	public var points(get, never) : Array<IPoint>;
+	/**
+		The amount of vertices in the polygon.
+	**/
 	public var length(get, never) : Int;
 	inline function get_length() return this.length;
 	inline function get_points() return this;
 
+	/**
+		Create a new Polygon shape.
+		@param points An optional array of vertices the polygon should use.
+	**/
 	public inline function new( ?points ) {
 		this = points == null ? [] : points;
 	}
 
+	@:dox(hide)
 	public inline function iterator() {
 		return new hxd.impl.ArrayIterator(this);
 	}
 
-	public function toPolygon( scale = 1. ) {
+	/**
+		Converts this IPolygon into a floating point-based Polygon.
+	**/
+	public function toPolygon( scale = 1. ) : Polygon {
 		return [for( p in points ) p.toPoint(scale)];
 	}
 
-	public function getBounds( ?b : IBounds ) {
+	/**
+		Returns the bounding box of the IPolygon.
+	**/
+	public function getBounds( ?b : IBounds ) : IBounds {
 		if( b == null ) b = new IBounds();
 		for( p in points )
 			b.addPoint(p);
 		return b;
 	}
 
+	/**
+		Combines this IPolygon and a given IPolygon `p` and returns the resulting IPolygons.
+		@param p The IPolygon to union with.
+		@param withHoles When enabled, keeps the holes in resulting polygons as a separate IPolygon.
+	**/
 	public function union( p : IPolygon, withHoles = true ) : IPolygons {
 		var c = new hxd.clipper.Clipper();
 		if( !withHoles ) c.resultKind = NoHoles;
@@ -42,14 +70,30 @@ abstract IPolygon(Array<IPoint>) from Array<IPoint> to Array<IPoint> {
 		return c.execute(Union, NonZero, NonZero);
 	}
 
+	/**
+		Calculates an intersection areas between this IPolygon and a given IPolygon `p` and returns the resulting IPolygons.
+		@param p The IPolygon to intersect with.
+		@param withHoles When enabled, keeps the holes in resulting polygons as a separate IPolygon. 
+	**/
 	public inline function intersection( p : IPolygon, withHoles = true ) : IPolygons {
 		return clipperOp(p, Intersection, withHoles);
 	}
 
+	/**
+		Subtracts the area of a given IPolygon `p` from this IPolygon and returns the resulting IPolygons.
+		@param p The IPolygon to subtract with.
+		@param withHoles When enabled, keeps the holes in resulting polygons as a separate IPolygon. 
+	**/
 	public inline function subtraction( p : IPolygon, withHoles = true ) : IPolygons {
 		return clipperOp(p, Difference, withHoles);
 	}
 
+	/**
+		Offsets the polygon edges by specified amount and returns the resulting IPolygons.
+		@param delta The offset amount.
+		@param kind The corner rounding method.
+		@param withHoles When enabled, keeps the holes in resulting polygons as a separate IPolygon. 
+	**/
 	public function offset( delta : Float, kind : OffsetKind, withHoles = true ) : IPolygons {
 		var c = new hxd.clipper.Clipper.ClipperOffset();
 		switch( kind ) {
@@ -73,6 +117,10 @@ abstract IPolygon(Array<IPoint>) from Array<IPoint> to Array<IPoint> {
 		return c.execute(op, NonZero, NonZero);
 	}
 
+	/**
+		Returns a new IPolygon containing a convex hull of this IPolygon.
+		See Monotone chain algorithm for more details.
+	**/
 	public function convexHull() {
 		var len = points.length;
 		if( len < 3 )
@@ -103,6 +151,9 @@ abstract IPolygon(Array<IPoint>) from Array<IPoint> to Array<IPoint> {
 		return hull;
 	}
 
+	/**
+		Tests if polygon points are in the clockwise order.
+	**/
 	public function isClockwise() {
 		var sum = 0.;
 		var p1 = points[points.length - 1];
@@ -113,6 +164,9 @@ abstract IPolygon(Array<IPoint>) from Array<IPoint> to Array<IPoint> {
 		return sum < 0; // Y axis is negative compared to classic maths
 	}
 
+	/**
+		Calculates total area of the IPolygon.
+	**/
 	public function area() {
 		var sum = 0.;
 		var p1 = points[points.length - 1];
@@ -127,6 +181,9 @@ abstract IPolygon(Array<IPoint>) from Array<IPoint> to Array<IPoint> {
 		return (p2.x - p1.x) * (t.y - p1.y) - (p2.y - p1.y) * (t.x - p1.x);
 	}
 
+	/**
+		Tests if the polygon is convex or concave.
+	**/
 	public function isConvex() {
 		var p1 = points[points.length - 2];
 		var p2 = points[points.length - 1];
@@ -142,10 +199,18 @@ abstract IPolygon(Array<IPoint>) from Array<IPoint> to Array<IPoint> {
 		return true;
 	}
 
+	/**
+		Reverses the IPolygon points ordering. Can be used to change polygon from anti-clockwise to clockwise.
+	**/
 	public function reverse() : Void {
 		this.reverse();
 	}
 
+	/**
+		Tests if Point `p` is inside this IPolygon.
+		@param p The point to test against.
+		@param isConvex Use simplified collision test suited for convex polygons. Results are undefined if polygon is concave.
+	**/
 	public function contains( p : Point, isConvex = false ) {
 		if( isConvex ) {
 			var p1 = points[points.length - 1];
@@ -173,7 +238,7 @@ abstract IPolygon(Array<IPoint>) from Array<IPoint> to Array<IPoint> {
 
 
 	/**
-		Creates a new optimized polygon by eliminating almost colinear edges according to epsilon distance.
+		Creates a new optimized polygon by eliminating almost colinear edges according to the epsilon distance.
 	**/
 	public function optimize( epsilon : Float ) : IPolygon {
 		var out = [];

+ 51 - 1
h2d/col/IPolygons.hx

@@ -1,27 +1,48 @@
 package h2d.col;
 import hxd.Math;
 
+/**
+	An abstract over an Array of `IPolygon` instances that define multiple polygonal shapes that can be collision-tested against.
+	@see `h2d.Polygons`
+**/
 @:forward(push,remove)
 abstract IPolygons(Array<IPolygon>) from Array<IPolygon> to Array<IPolygon> {
-
+	/**
+		An underlying IPolygon array.
+	**/
 	public var polygons(get, never) : Array<IPolygon>;
+	/**
+		The amount of polygons in the IPolygons instance.
+	**/
 	public var length(get, never) : Int;
 	inline function get_length() return this.length;
 
 	inline function get_polygons() return this;
 
+	/**
+		Create a new IPolygons instance.
+		@param polygons An optional list of polygons to use.
+	**/
 	public inline function new( ?polygons ) {
 		this = polygons == null ? [] : polygons;
 	}
 
+	@:dox(hide)
 	public inline function iterator() {
 		return new hxd.impl.ArrayIterator(this);
 	}
 
+	/**
+		Converts the IPolygons instance to the floating point-based Polygons.
+	**/
 	public function toPolygons( scale = 1. ) : Polygons {
 		return [for( p in polygons ) p.toPolygon(scale)];
 	}
 
+	/**
+		Returns bounding box of all IPolygon instances in IPolygons.
+		@param b Optional Bounds instance to be filled. Returns new Bounds instance if `null`.
+	**/
 	public function getBounds( ?b : IBounds ) {
 		if( b == null ) b = new IBounds();
 		for( p in polygons )
@@ -29,6 +50,11 @@ abstract IPolygons(Array<IPolygon>) from Array<IPolygon> to Array<IPolygon> {
 		return b;
 	}
 
+	/**
+		Combines this IPolygons and given IPolygons `p` and returns resulting IPolygons.
+		@param p Optional IPolygons to union with. When not set, unions all polygons in this IPolygons.
+		@param withHoles When enabled, keeps the holes in resulting polygons as a separate IPolygon.
+	**/
 	public function union( ?p : IPolygons, withHoles = true ) : IPolygons {
 		var c = new hxd.clipper.Clipper();
 		if( !withHoles ) c.resultKind = NoHoles;
@@ -37,14 +63,30 @@ abstract IPolygons(Array<IPolygon>) from Array<IPolygon> to Array<IPolygon> {
 		return c.execute(Union, NonZero, NonZero);
 	}
 
+	/**
+		Calculates an intersection areas between this IPolygons and given IPolygons `p` and returns resulting IPolygons.
+		@param p The IPolygons to intersect with.
+		@param withHoles When enabled, keeps the holes in resulting polygons as a separate IPolygon. 
+	**/
 	public inline function intersection( p : IPolygons, withHoles = true ) : IPolygons {
 		return clipperOp(p, Intersection, withHoles);
 	}
 
+	/**
+		Subtracts the area of given IPolygons `p` from this IPolygons and returns resulting IPolygons.
+		@param p The IPolygons to subtract with.
+		@param withHoles When enabled, keeps the holes in resulting polygons as a separate IPolygon. 
+	**/
 	public inline function subtraction( p : IPolygons, withHoles = true ) : IPolygons {
 		return clipperOp(p, Difference, withHoles);
 	}
 
+	/**
+		Offsets polygon edges by specified amount and returns resulting IPolygons.
+		@param delta The offset amount.
+		@param kind The corner rounding method.
+		@param withHoles When enabled, keeps the holes in resulting polygons as a separate IPolygon. 
+	**/
 	public function offset( delta : Float, kind : IPolygon.OffsetKind, withHoles = true ) : IPolygons {
 		if( this.length == 0 )
 			return new IPolygons();
@@ -70,6 +112,11 @@ abstract IPolygons(Array<IPolygon>) from Array<IPolygon> to Array<IPolygon> {
 		return c.execute(op, NonZero, NonZero);
 	}
 
+	/**
+		Tests if Point `p` is inside this IPolygons.
+		@param p The point to test against.
+		@param isConvex Use simplified collision test suited for convex polygons. Results are undefined if polygon is concave.
+	**/
 	public function contains( p : Point, isConvex = false ) {
 		for( pl in polygons )
 			if( pl.contains(p, isConvex) )
@@ -77,6 +124,9 @@ abstract IPolygons(Array<IPolygon>) from Array<IPolygon> to Array<IPolygon> {
 		return false;
 	}
 
+	/**
+		Creates a set of new optimized polygons by eliminating almost colinear edges according to the epsilon distance.
+	**/
 	public function optimize( epsilon : Float ) : IPolygons {
 		return [for( p in polygons ) p.optimize(epsilon)];
 	}

+ 39 - 1
h2d/col/Line.hx

@@ -1,19 +1,38 @@
 package h2d.col;
 
+/**
+	An infinite 2D line going through two specified Points.
+**/
 class Line {
-
+	/**
+		The first line point.
+	**/
 	public var p1 : Point;
+	/**
+		The second line point.
+	**/
 	public var p2 : Point;
 
+	/**
+		Create a new Line instance.
+		@param p1 The first line point.
+		@param p2 The second line point.
+	**/
 	public inline function new(p1,p2) {
 		this.p1 = p1;
 		this.p2 = p2;
 	}
 
+	/**
+		Returns a positive value if Point `p` is on the right side of the Line axis and negative if it's on the left.
+	**/
 	public inline function side( p : Point ) {
 		return (p2.x - p1.x) * (p.y - p1.y) - (p2.y - p1.y) * (p.x - p1.x);
 	}
 
+	/**
+		Projects Point `p` onto the Line axis and return new Point instance with a result.
+	**/
 	public inline function project( p : Point ) {
 		var dx = p2.x - p1.x;
 		var dy = p2.y - p1.y;
@@ -21,6 +40,10 @@ class Line {
 		return new Point(dx * k + p1.x, dy * k + p1.y);
 	}
 
+	/**
+		Returns an intersection Point between given Line `l` and this Line with both treated as infinite lines.
+		Returns `null` if lines are almost colinear (less than epsilon value difference)
+	**/
 	public inline function intersect( l : Line ) {
 		var d = (p1.x - p2.x) * (l.p1.y - l.p2.y) - (p1.y - p2.y) * (l.p1.x - l.p2.x);
 		if( hxd.Math.abs(d) < hxd.Math.EPSILON )
@@ -30,6 +53,11 @@ class Line {
 		return new Point( (a * (l.p1.x - l.p2.x) - (p1.x - p2.x) * b) / d, (a * (l.p1.y - l.p2.y) - (p1.y - p2.y) * b) / d );
 	}
 
+	/**
+		Tests for intersection between given Line `l` and this Line with both treated as infinite lines.
+		Returns `false` if lines are almost colinear (less than epsilon value difference).
+		Otherwise returns `true`, and fill Point `pt` with intersection point.
+	**/
 	public inline function intersectWith( l : Line, pt : Point ) {
 		var d = (p1.x - p2.x) * (l.p1.y - l.p2.y) - (p1.y - p2.y) * (l.p1.x - l.p2.x);
 		if( hxd.Math.abs(d) < hxd.Math.EPSILON )
@@ -41,6 +69,10 @@ class Line {
 		return true;
 	}
 
+	/**
+		Returns a squared distance from Line axis to Point `p`.
+		Cheaper to calculate than `distance` and can be used for more optimal comparison operations.
+	**/
 	public inline function distanceSq( p : Point ) {
 		var dx = p2.x - p1.x;
 		var dy = p2.y - p1.y;
@@ -50,6 +82,9 @@ class Line {
 		return mx * mx + my * my;
 	}
 
+	/**
+		Returns a distance from Line axis to Point `p`.
+	**/
 	public inline function distance( p : Point ) {
 		return hxd.Math.sqrt(distanceSq(p));
 	}
@@ -63,6 +98,9 @@ class Line {
 		return hxd.Math.atan2(dy, dx);
 	}
 
+	/**
+		The distance between Line starting Point `p1` and ending Point `p2`.
+	**/
 	public inline function length():Float {
 		var dx = p2.x - p1.x;
 		var dy = p2.y - p1.y;

+ 119 - 2
h2d/col/Matrix.hx

@@ -2,7 +2,13 @@ package h2d.col;
 import hxd.Math;
 
 /**
-	Affine 2D 2x3 matrix
+	An affine 2D 2x3 matrix.
+
+	Matrix properties are as follows:
+	```
+	[a, c, x]
+	[b, d, y]
+	```
 **/
 class Matrix {
 
@@ -15,26 +21,57 @@ class Matrix {
 	public var x : Float;
 	public var y : Float;
 
+	/**
+		Create a new identity Matrix.
+	**/
 	public function new() {
 		identity();
 	}
 
+	/**
+		Sets the matrix values to ones that would perform no transformation.
+		```
+		[1, 0, 0]
+		[0, 1, 0]
+		```
+	**/
 	public inline function identity() {
 		a = 1; b = 0; c = 0; d = 1;
 		x = 0; y = 0;
 	}
 
+	/**
+		Sets the matrix values to ones that would only move the transformed positions by given `x` and `y`.
+		```
+		[1, 0, x]
+		[0, 1, y]
+		```
+	**/
 	public inline function initTranslate(x, y) {
 		a = 1; b = 0; c = 0; d = 1;
 		this.x = x;
 		this.y = y;
 	}
 
+	/**
+		Sets the matrix values to ones that would only scale the transformed positions by given `sx` and `sy`.
+		```
+		[sx, 0, 0]
+		[0, sy, 0]
+		```
+	**/
 	public inline function initScale(sx, sy) {
 		a = sx; b = 0; c = 0; d = sy;
 		x = 0; y = 0;
 	}
 
+	/**
+		Sets the matrix values to ones that would only rotate the transformed position by given `angle`.
+		```
+		[cos(angle), -sin(angle), 0]
+		[sin(angle),  cos(angle), 0]
+		```
+	**/
 	public inline function initRotate(angle) {
 		var cos = Math.cos(angle);
 		var sin = Math.sin(angle);
@@ -46,6 +83,13 @@ class Matrix {
 		y = 0;
 	}
 
+	/**
+		Sets the matrix values to ones that would only skew the transformed position by given `sx` and `sy`.
+		```
+		[1, tan(sx), 0]
+		[tan(sy), 1, 0]
+		```
+	**/
 	public inline function initSkew(sx, sy) {
 		var tanX = Math.tan(sx);
 		var tanY = Math.tan(sy);
@@ -57,14 +101,24 @@ class Matrix {
 		y = 0;
 	}
 
+	/**
+		Inverts the matrix to perform the opposite transformation. Can be used to undo the previously applied transformation.
+		@see `Matrix.inverse`
+	**/
 	public function invert() {
 		inverse(this);
 	}
 
+	/**
+		Returns the determinant of the Matrix `a`, `b`, `c` and `d` values.
+	**/
 	public inline function getDeterminant() {
 		return a * d - b * c;
 	}
 
+	/**
+		Sets this Matrix value to be the inverse of the given Matrix `m`.
+	**/
 	public function inverse( m : Matrix ) {
 		var a = m.a, b = m.b;
 		var c = m.c, d = m.d;
@@ -78,36 +132,67 @@ class Matrix {
 		this.y = (x * b - a * y) * invDet;
 	}
 
+	/**
+		Returns a new Point that is a result of transforming Point `pt` by this Matrix.
+	**/
 	public inline function transform( pt : Point ) {
 		return new Point(pt.x * a + pt.y * c + x, pt.x * b + pt.y * d + y);
 	}
 
+	/**
+		Applies translation transform to Matrix by given `x` and `y`.
+	**/
 	public inline function translate( x : Float, y : Float ) {
 		this.x += x;
 		this.y += y;
 	}
 
+	/**
+		Applies translation transform on X-axis to Matrix by given `x`. Equivalent of `matrix.x += x`.
+	**/
 	public inline function translateX( x : Float ) {
 		this.x += x;
 	}
 
+	/**
+		Applies translation transform on Y-axis to Matrix by given `y`. Equivalent of `matrix.y += y`.
+	**/
 	public inline function translateY( y : Float ) {
 		this.y += y;
 	}
 
+	/**
+		Transforms given `x` and `y` with current Matrix values (excluding translation) and
+		applies translation transform to Matrix by resulting `x` and `y`.
+	**/
 	public inline function prependTranslate( x : Float, y : Float ) {
 		this.x += a * x + c * y;
 		this.y += b * x + d * y;
 	}
 
+	/**
+		Transforms given `x` with current Matrix values (excluding translation) and
+		applies translation transform on X-axis to Matrix by resulting `x` and `y`.
+		Equivalent of `matrix.x += matrix.a * x`.
+	**/
 	public inline function prependTranslateX( x : Float ) {
 		this.x += a * x;
 	}
 
+	/**
+		Transforms given `y` with current Matrix values (excluding translation) and
+		applies translation transform on Y-axis to Matrix by resulting `y`.
+		Equivalent of `matrix.y += matrix.d * y`.
+	**/
 	public inline function prependTranslateY( y : Float ) {
 		this.y += d * y;
 	}
 
+	/**
+		Concatenates Matrix `a` and `b` and stores the result in this Matrix. 
+		Matrix can be the target of of it's own `multiply`.
+		Keep in mind that order of matrixes matter in concatenation.
+	**/
 	public function multiply( a : Matrix, b : Matrix ) {
 		var aa = a.a, ab = a.b, ac = a.c, ad = a.d, ax = a.x, ay = a.y;
 		var ba = b.a, bb = b.b, bc = b.c, bd = b.d, bx = b.x, by = b.y;
@@ -119,6 +204,10 @@ class Matrix {
 		this.y = ax * bb + ay * bd + by;
 	}
 
+	/**
+		Returns a Point with a total scaling applied by the Matrix.
+		@param p Optional Point instance. If provided, sets values of given Point and returns it. Otherwise returns new Point instance.
+	**/
 	public inline function getScale(?p: h2d.col.Point) {
 		if(p == null)
 			p = new h2d.col.Point();
@@ -131,7 +220,9 @@ class Matrix {
 		return p;
 	}
 
-
+	/**
+		Multiplies the `a`, `c` and `x` by given `sx` and `b`, `d` and `y` by `sy`.
+	**/
 	public inline function scale( sx : Float, sy : Float ) {
 		a *= sx;
 		c *= sx;
@@ -141,23 +232,35 @@ class Matrix {
 		y *= sy;
 	}
 
+	/**
+		Multiplies the `a`, `c` and `x` by given `sx`.
+	**/
 	public inline function scaleX( sx : Float ) {
 		a *= sx;
 		c *= sx;
 		x *= sx;
 	}
 
+	/**
+		Multiplies the `b`, `d` and `y` by `sy`.
+	**/
 	public inline function scaleY( sy : Float ) {
 		b *= sy;
 		d *= sy;
 		y *= sy;
 	}
 
+	/**
+		Applies rotation transform to the Matrix by given `angle`.
+	**/
 	public function rotate(angle: Float) {
 		tmp.initRotate(angle);
 		multiply(this, tmp);
 	}
 
+	/**
+		Applies skewing transform to the Matrix by given `sx` and `sy`.
+	**/
 	public function skew( sx : Float, sy : Float ) {
 		var aa = this.a, ab = this.b, ac = this.c, ad = this.d, ax = this.x, ay = this.y;
 		// [1, tan(sx), 0]
@@ -172,6 +275,9 @@ class Matrix {
 		this.y = ax * bb + ay;
 	}
 
+	/**
+		Applies skewing transform on X-axis to the Matrix by given `sx`.
+	**/
 	public function skewX( sx : Float ) {
 		// [1, tan(sx), 0]
 		// [0, 1      , 0]
@@ -181,6 +287,9 @@ class Matrix {
 		this.x = x + y * bc;
 	}
 
+	/**
+		Applies skewing transform on Y-axis to the Matrix by given `sy`.
+	**/
 	public function skewY( sy : Float ) {
 		// [1, tan(sx), 0]
 		// [tan(sy), 1, 0]
@@ -190,6 +299,9 @@ class Matrix {
 		this.y = x * bb + y;
 	}
 
+	/**
+		Returns a copy of this Matrix.
+	**/
 	public function clone() {
 		var m = new Matrix();
 		m.a = a;
@@ -201,12 +313,17 @@ class Matrix {
 		return m;
 	}
 
+	/**
+		Returns a Point with `x` and `y` of the Matrix.
+		@param p Optional Point instance to use. Otherwise returns new instance.
+	**/
 	public inline function getPosition( ?p : h2d.col.Point ) {
 		if( p == null ) p = new h2d.col.Point();
 		p.set(x,y);
 		return p;
 	}
 
+	@:dox(hide)
 	public function toString() {
 		return "MAT=[\n" +
 			"  [ " + Math.fmt(a) + ", " + Math.fmt(b) + " ]\n" +

+ 35 - 9
h2d/col/PixelsCollider.hx

@@ -1,47 +1,70 @@
 package h2d.col;
 
 /**
-	A Pixels collider. Checks for pixel color value under point to be above the cutoff value.
-	Note that it checks as `channel > cutoff`, not `channel >= cutoff`, hence value of 255 will always be considered below cutoff.
+	An `hxd.Pixels`-based collider. Checks for pixel color value under point to be above the cutoff value.
+	
+	Note that it checks as `channel > cutoff`, not `channel >= cutoff`, hence cutoff value of 255 would never pass the test.
 **/
 class PixelsCollider implements Collider {
 
+	/**
+		The source pixel data which is tested against.
+	**/
 	public var pixels : hxd.Pixels;
 
 	/**
-		The red channel cutoff value in range of -1...255 (default : 255)
+		The red channel cutoff value in range of -1...255
+
+		Set to 255 to always fail the test.
+		@default 255
 	**/
 	public var redCutoff : Int;
 	/**
-		The green channel cutoff value in range of -1...255 (default : 255)
+		The green channel cutoff value in range of -1...255
+
+		Set to 255 to always fail the test.
+		@default 255
 	**/
 	public var greenCutoff : Int;
 	/**
-		The blue channel cutoff value in range of -1...255 (default : 255)
+		The blue channel cutoff value in range of -1...255
+
+		Set to 255 to always fail the test.
+		@default 255
 	**/
 	public var blueCutoff : Int;
 
 	/**
-		The alpha channel cutoff value in range of -1...255 (default : 127)
+		The alpha channel cutoff value in range of -1...255
+
+		Set to 255 to always fail the test.
+		@default 127
 	**/
 	public var alphaCutoff : Int;
 
 	/**
-		If true, will collide if any channel is above cutoff. Otherwise will collide only if all channels above their cutoff values. (default : true)
+		If true, will collide if any channel is above cutoff. Otherwise will collide only if all channels above their cutoff values.
+		@default true
 	**/
 	public var collideOnAny : Bool;
 
 	/**
-		Horizontal stretch of pixels to check for collision. (default : 1)
+		Horizontal stretch of pixels to check for collision.
 	**/
 	public var scaleX : Float = 1;
 	/**
-		Vertical stretch of pixels to check for collision. (default : 1)
+		Vertical stretch of pixels to check for collision.
 	**/
 	public var scaleY : Float = 1;
 
 	/**
 		Create new BitmapCollider with specified bitmap, channel cutoff values and check mode.
+		@param pixels The source pixel data which is tested against.
+		@param alphaCutoff The alpha channel cutoff value.
+		@param redCutoff The red channel cutoff value.
+		@param greenCutoff The green channel cutoff value.
+		@param blueCutoff The blue channel cutoff value.
+		@param collideOnAny Whether to pass the collision check if any channel is above the threshold or if all channels should pass the test.
 	**/
 	public function new(pixels: hxd.Pixels, alphaCutoff:Int = 127, redCutoff:Int = 255, greenCutoff = 255, blueCutoff = 255, collideOnAny = true) {
 		this.pixels = pixels;
@@ -52,6 +75,9 @@ class PixelsCollider implements Collider {
 		this.collideOnAny = collideOnAny;
 	}
 
+	/**
+		Checks if the pixel under given Point `p` passes the threshold test.
+	**/
 	public function contains( p : Point ) {
 		var ix : Int = Math.floor(p.x / scaleX);
 		var iy : Int = Math.floor(p.y / scaleY);

+ 92 - 7
h2d/col/Point.hx

@@ -1,60 +1,106 @@
 package h2d.col;
 import hxd.Math;
 
+/**
+	A simple 2D position/vector container.
+	@see `h2d.col.IPoint`
+**/
 class Point #if apicheck implements h2d.impl.PointApi<Point,Matrix> #end {
 
+	/**
+		The horizontal position of the point.
+	**/
 	public var x : Float;
+	/**
+		The vertical position of the point.
+	**/
 	public var y : Float;
 
 	// -- gen api
 
+	/**
+		Create a new Point instance.
+		@param x The horizontal position of the point.
+		@param y The vertical position of the point.
+	**/
 	public inline function new(x = 0., y = 0.) {
 		this.x = x;
 		this.y = y;
 	}
 
+	/**
+		Returns squared distance between this Point and given Point `p`.
+	**/
 	public inline function distanceSq( p : Point ) {
 		var dx = x - p.x;
 		var dy = y - p.y;
 		return dx * dx + dy * dy;
 	}
 
-	public inline function distance( p : Point ) {
+	/**
+		Returns a distance between this Point and given Point `p`.
+	**/
+	public inline function distance( p : Point ) : Float {
 		return Math.sqrt(distanceSq(p));
 	}
 
-	public function toString() {
+	@:dox(hide)
+	public function toString() : String {
 		return "{" + Math.fmt(x) + "," + Math.fmt(y) + "}";
 	}
 
-	public inline function sub( p : Point ) {
+	/**
+		Substracts Point `p` from this Point and returns new Point with the result.
+	**/
+	public inline function sub( p : Point ) : Point {
 		return new Point(x - p.x, y - p.y);
 	}
 
-	public inline function add( p : Point ) {
+	/**
+		Adds Point `p` to this Point and returns new Point with the result.
+	**/
+	public inline function add( p : Point ) : Point {
 		return new Point(x + p.x, y + p.y);
 	}
 
+	/**
+		Returns a new Point with the position of this Point multiplied by a given scalar `v`.
+	**/
 	public inline function multiply( v : Float ) {
 		return new Point(x * v, y * v);
 	}
 
+	/**
+		Tests if this Point position equals to `other` Point position.
+	**/
 	public inline function equals( other : Point ) : Bool {
 		return x == other.x && y == other.y;
 	}
 
-	public inline function dot( p : Point ) {
+	/**
+		Returns a dot product between this Point and given Point `p`.
+	**/
+	public inline function dot( p : Point ) : Float {
 		return x * p.x + y * p.y;
 	}
 
+	/**
+		Returns squared length of this Point.
+	**/
 	public inline function lengthSq() {
 		return x * x + y * y;
 	}
 
-	public inline function length() {
+	/**
+		Returns length (distance to `0,0`) of this Point.
+	**/
+	public inline function length() : Float {
 		return Math.sqrt(lengthSq());
 	}
 
+	/**
+		Normalizes the Point.
+	**/
 	public inline function normalize() {
 		var k = lengthSq();
 		if( k < Math.EPSILON ) k = 0 else k = Math.invSqrt(k);
@@ -62,40 +108,64 @@ class Point #if apicheck implements h2d.impl.PointApi<Point,Matrix> #end {
 		y *= k;
 	}
 
+	/**
+		Returns a new Point with the normalized values of this Point.
+	**/
 	public inline function normalized() {
 		var k = lengthSq();
 		if( k < Math.EPSILON ) k = 0 else k = Math.invSqrt(k);
 		return new h2d.col.Point(x*k,y*k);
 	}
 
+	/**
+		Sets the Point `x,y` with given values.
+	**/
 	public inline function set(x=0.,y=0.) {
 		this.x = x;
 		this.y = y;
 	}
 
+	/**
+		Copies `x,y` from given Point `p` to this Point.
+	**/
 	public inline function load( p : h2d.col.Point ) {
 		this.x = p.x;
 		this.y = p.y;
 	}
 
+	/**
+		Multiplies `x,y` by scalar `f` and returns this Point.
+	**/
 	public inline function scale( f : Float ) {
 		x *= f;
 		y *= f;
 	}
 
-	public inline function clone() {
+	/**
+		Returns a copy of this Point.
+	**/
+	public inline function clone() : Point {
 		return new Point(x, y);
 	}
 
+	/**
+		Returns a cross product between this Point and a given Point `p`.
+	**/
 	public inline function cross( p : Point ) {
 		return x * p.y - y * p.x;
 	}
 
+	/**
+		Sets this Point position to a result of linear interpolation between Points `p1` and `p2` at the interpolant position `k`.
+	**/
 	public inline function lerp( a : Point, b : Point, k : Float ) {
 		x = hxd.Math.lerp(a.x, b.x, k);
 		y = hxd.Math.lerp(a.y, a.y, k);
 	}
 
+	/**
+		Applies a given Matrix `m` transformation to this Point position.
+	**/
 	public inline function transform( m : Matrix ) {
 		var mx = m.a * x + m.c * y + m.x;
 		var my = m.b * x + m.d * y + m.y;
@@ -103,12 +173,18 @@ class Point #if apicheck implements h2d.impl.PointApi<Point,Matrix> #end {
 		this.y = my;
 	}
 
+	/**
+		Returns a new Point with a result of applying a Matrix `m` to this Point position.
+	**/
 	public inline function transformed( m : Matrix ) {
 		var mx = m.a * x + m.c * y + m.x;
 		var my = m.b * x + m.d * y + m.y;
 		return new Point(mx,my);
 	}
 
+	/**
+		Applies a given 2x2 Matrix `m` transformation to this Point position.
+	**/
 	public inline function transform2x2( m : Matrix ) {
 		var mx = m.a * x + m.c * y;
 		var my = m.b * x + m.d * y;
@@ -116,6 +192,9 @@ class Point #if apicheck implements h2d.impl.PointApi<Point,Matrix> #end {
 		this.y = my;
 	}
 
+	/**
+		Returns a new Point with a result of applying a 2x2 Matrix `m` to this Point position.
+	**/
 	public inline function transformed2x2( m : Matrix ) {
 		var mx = m.a * x + m.c * y;
 		var my = m.b * x + m.d * y;
@@ -125,10 +204,16 @@ class Point #if apicheck implements h2d.impl.PointApi<Point,Matrix> #end {
 
 	// -- end
 
+	/**
+		Converts this point to integer point scaled by provided scalar `scale` (rounded).
+	**/
 	public inline function toIPoint( scale = 1. ) {
 		return new IPoint(Math.round(x * scale), Math.round(y * scale));
 	}
 
+	/**
+		Rotates this Point around `0,0` by a given `angle`.
+	**/
 	public inline function rotate( angle : Float ) {
 		var c = Math.cos(angle);
 		var s = Math.sin(angle);

+ 65 - 4
h2d/col/Polygon.hx

@@ -1,18 +1,33 @@
 package h2d.col;
 import hxd.Math;
 
+/**
+	An abstract around an Array of `Point`s that define a polygonal shape that can be collision-tested against.
+	@see `h2d.col.IPolygon`
+**/
 @:forward(push,remove,insert,copy)
 abstract Polygon(Array<Point>) from Array<Point> to Array<Point> {
-
+	
+	/**
+		The underlying Array of vertices.
+	**/
 	public var points(get, never) : Array<Point>;
+	/**
+		The amount of vertices in the polygon.
+	**/
 	public var length(get, never) : Int;
 	inline function get_length() return this.length;
 	inline function get_points() return this;
 
+	/**
+		Create a new Polygon shape.
+		@param points An optional array of vertices the polygon should use.
+	**/
 	public inline function new( ?points ) {
 		this = points == null ? [] : points;
 	}
 
+	@:dox(hide)
 	public inline function iterator() {
 		return new hxd.impl.ArrayIterator(this);
 	}
@@ -26,6 +41,9 @@ abstract Polygon(Array<Point>) from Array<Point> to Array<Point> {
 		return new hxd.earcut.Earcut().triangulate(points);
 	}
 
+	/**
+		Returns new Segments instance containing polygon edges.
+	**/
 	public function toSegments() : Segments {
 		var segments = [];
 		var p1 = points[points.length - 1];
@@ -37,10 +55,17 @@ abstract Polygon(Array<Point>) from Array<Point> to Array<Point> {
 		return segments;
 	}
 
-	public function toIPolygon( scale = 1. ) {
+	/**
+		Converts Polygon to Int-based IPolygon.
+	**/
+	public function toIPolygon( scale = 1. ) : IPolygon {
 		return [for( p in points ) p.toIPoint(scale)];
 	}
 
+	/**
+		Returns bounding box of the Polygon.
+		@param b Optional Bounds instance to be filled. Returns new Bounds instance if `null`.
+	**/
 	public function getBounds( ?b : Bounds ) {
 		if( b == null ) b = new Bounds();
 		for( p in points )
@@ -48,6 +73,10 @@ abstract Polygon(Array<Point>) from Array<Point> to Array<Point> {
 		return b;
 	}
 
+	/**
+		Returns new `PolygonCollider` instance containing this Polygon.
+		@param isConvex Use simplified collision test suited for convex polygons. Results are undefined if polygon is concave.
+	**/
 	public function getCollider(isConvex : Bool = false) {
 		return new PolygonCollider([this], isConvex);
 	}
@@ -58,7 +87,10 @@ abstract Polygon(Array<Point>) from Array<Point> to Array<Point> {
 		return a.x < b.x ? -1 : 1;
 	}
 
-	//see Monotone_chain convex hull algorithm
+	/**
+		Returns a new Polygon containing a convex hull of this Polygon.
+		See Monotone chain algorithm for more details.
+	**/
 	public function convexHull() {
 		var len = points.length;
 		if( points.length < 3 )
@@ -89,6 +121,9 @@ abstract Polygon(Array<Point>) from Array<Point> to Array<Point> {
 	   return hull;
 	}
 
+	/**
+		Tests if polygon points are in the clockwise order.
+	**/
 	public function isClockwise() {
 		var sum = 0.;
 		var p1 = points[points.length - 1];
@@ -99,6 +134,9 @@ abstract Polygon(Array<Point>) from Array<Point> to Array<Point> {
 		return sum < 0; // Y axis is negative compared to classic maths
 	}
 
+	/**
+		Calculates total area of the Polygon.
+	**/
 	public function area() {
 		var sum = 0.;
 		var p1 = points[points.length - 1];
@@ -109,6 +147,9 @@ abstract Polygon(Array<Point>) from Array<Point> to Array<Point> {
 		return Math.abs(sum) * 0.5;
 	}
 
+	/**
+		Calculates a centroid of the Polygon and returns its position.
+	**/
 	public function centroid() {
 		var A = 0.;
 		var cx = 0.;
@@ -134,6 +175,9 @@ abstract Polygon(Array<Point>) from Array<Point> to Array<Point> {
 		return (p2.x - p1.x) * (t.y - p1.y) - (p2.y - p1.y) * (t.x - p1.x);
 	}
 
+	/**
+		Tests if polygon is convex or concave.
+	**/
 	public function isConvex() {
 		if(points.length < 4) return true;
 		var p1 = points[points.length - 2];
@@ -150,16 +194,27 @@ abstract Polygon(Array<Point>) from Array<Point> to Array<Point> {
 		return true;
 	}
 
+	/**
+		Reverses the Polygon points ordering. Can be used to change polygon from anti-clockwise to clockwise.
+	**/
 	public function reverse() : Void {
 		this.reverse();
 	}
 
+	/**
+		Transforms Polygon points by provided matrix.
+	**/
 	public function transform(mat: h2d.col.Matrix) {
 		for( i in 0...points.length ) {
 			points[i] = mat.transform(points[i]);
 		}
 	}
 
+	/**
+		Tests if Point `p` is inside this Polygon.
+		@param p The point to test against.
+		@param isConvex Use simplified collision test suited for convex polygons. Results are undefined if polygon is concave.
+	**/
 	@:noDebug
 	public function contains( p : Point, isConvex = false ) {
 		if( isConvex ) {
@@ -186,6 +241,12 @@ abstract Polygon(Array<Point>) from Array<Point> to Array<Point> {
 		}
 	}
 
+	/**
+		Returns closest Polygon vertex to Point `pt` within set maximum distance.
+		@param pt The point to test against.
+		@param maxDist Maximum distance vertex can be away from `pt` before it no longer considered close.
+		@returns A `Point` instance in the Polygon representing closest vertex (not the copy). `null` if no vertices were found near the `pt` within `maxDist`.
+	**/
 	public function findClosestPoint(pt : h2d.col.Point, maxDist : Float) {
 		var closest = null;
 		var minDist = maxDist * maxDist;
@@ -306,7 +367,7 @@ abstract Polygon(Array<Point>) from Array<Point> to Array<Point> {
 	}
 
 	/**
-		check if polygon self-insterset
+		Check if polygon self-intersect
 	**/
 	public function selfIntersecting() {
 		if(points.length < 4) return false;

+ 13 - 1
h2d/col/PolygonCollider.hx

@@ -1,8 +1,17 @@
 package h2d.col;
 
+/**
+	A `Collider` wrapper around `Polygons` to enable using those for hit-testing testing.
+**/
 class PolygonCollider implements Collider {
-
+	/**
+		The Polygons instance used for collision checks.
+	**/
 	public var polygons : Polygons;
+	/**
+		Whether Polygons is convex or concave.
+		Convex polygons are cheaper to test against.
+	**/
 	public var isConvex : Bool;
 
 	/**
@@ -13,6 +22,9 @@ class PolygonCollider implements Collider {
 		this.isConvex = isConvex;
 	}
 
+	/**
+		Test is Point `p` is inside `polygons`.
+	**/
 	public function contains( p : Point ) {
 		if (polygons == null) return false;
 		return polygons.contains(p, isConvex);

+ 35 - 1
h2d/col/Polygons.hx

@@ -1,26 +1,48 @@
 package h2d.col;
 import hxd.Math;
 
+/**
+	An abstract over an Array of `Polygon` instances that define multiple polygonal shapes that can be collision-tested against.
+	@see `h2d.IPolygons`
+**/
 @:forward(push,remove)
 abstract Polygons(Array<Polygon>) from Array<Polygon> to Array<Polygon> {
-
+	
+	/**
+		An underlying Polygon array.
+	**/
 	public var polygons(get, never) : Array<Polygon>;
+	/**
+		The amount of polygons in the Polygons instance.
+	**/
 	public var length(get, never) : Int;
 	inline function get_length() return this.length;
 	inline function get_polygons() return this;
 
+	/**
+		Create a new Polygons instance.
+		@param polygons An optional list of polygons to use.
+	**/
 	public inline function new( ?polygons ) {
 		this = polygons == null ? [] : polygons;
 	}
 
+	@:dox(hide)
 	public inline function iterator() {
 		return new hxd.impl.ArrayIterator(this);
 	}
 
+	/**
+		Converts Polygons instance to Int-based IPolygons.
+	**/
 	public function toIPolygons( scale = 1. ) : IPolygons {
 		return [for( p in polygons ) p.toIPolygon(scale)];
 	}
 
+	/**
+		Returns bounding box of all Polygon instances in Polygons.
+		@param b Optional Bounds instance to be filled. Returns new Bounds instance if `null`.
+	**/
 	public function getBounds( ?b : Bounds ) {
 		if( b == null ) b = new Bounds();
 		for( p in polygons )
@@ -28,10 +50,19 @@ abstract Polygons(Array<Polygon>) from Array<Polygon> to Array<Polygon> {
 		return b;
 	}
 
+	/**
+		Returns new `PolygonCollider` instance containing this Polygons.
+		@param isConvex Use simplified collision test suited for convex polygons. Results are undefined if polygon is concave.
+	**/
 	public function getCollider(isConvex : Bool = false) {
 		return new PolygonCollider(this, isConvex);
 	}
 
+	/**
+		Tests if Point `p` is inside any of the Polygon instances in Polygons.
+		@param p The point to test against.
+		@param isConvex Use simplified collision test suited for convex polygons. Results are undefined if polygon is concave.
+	**/
 	public function contains( p : Point, isConvex = false ) {
 		for( pl in polygons )
 			if( pl.contains(p, isConvex) )
@@ -39,6 +70,9 @@ abstract Polygons(Array<Polygon>) from Array<Polygon> to Array<Polygon> {
 		return false;
 	}
 
+	/**
+		Optimizes all polygons and returns new Polygons instances. See [h2d.col.Polygon.optimize].
+	**/
 	public function optimize( epsilon : Float ) : Polygons {
 		return [for( p in polygons ) p.optimize(epsilon)];
 	}

+ 3 - 0
h2d/col/Polynomial.hx

@@ -112,6 +112,9 @@ private class QR {
 
 }
 
+/**
+	See `Polynomial.regress`.
+**/
 class Polynomial {
 
 	/**

+ 29 - 1
h2d/col/Ray.hx

@@ -1,28 +1,50 @@
 package h2d.col;
 import hxd.Math;
 
+/**
+	A raycast from the given position in a specified direction.
+**/
 class Ray {
 
+	/** X position of the ray start. **/
 	public var px : Float;
+	/** Y position of the ray start. **/
 	public var py : Float;
+	/** X normal of the ray direction. **/
 	public var lx : Float;
+	/** Y normal of the ray direction. **/
 	public var ly : Float;
 
+	/**
+		Create a new Ray instance.
+	**/
 	public inline function new() {
 	}
 
+	/**
+		Returns a positive value if Point `p` is on the right side of the Ray axis and negative if it's on the left.
+	**/
 	public inline function side( p : Point ) {
 		return lx * (p.y - py) - ly * (p.x - px);
 	}
 
+	/**
+		Returns a new Point containing the Ray vector with specified length.
+	**/
 	public inline function getPoint( distance : Float ) {
 		return new Point(px + distance * lx, py + distance * ly);
 	}
 
+	/**
+		Returns new Point containing Ray starting position.
+	**/
 	public inline function getPos() {
 		return new Point(px, py);
 	}
-
+	
+	/**
+		Returns new Point containing Ray direction.
+	**/
 	public inline function getDir() {
 		return new Point(lx, ly);
 	}
@@ -35,6 +57,9 @@ class Ray {
 		ly *= l;
 	}
 
+	/**
+		Returns a new Ray starting at Point `p1` and pointing at Point `p2`.
+	**/
 	public static inline function fromPoints( p1 : Point, p2 : Point ) {
 		var r = new Ray();
 		r.px = p1.x;
@@ -45,6 +70,9 @@ class Ray {
 		return r;
 	}
 
+	/**
+		Returns a new Ray at given position and direction.
+	**/
 	public static inline function fromValues( x, y, dx, dy ) {
 		var r = new Ray();
 		r.px = x;

+ 34 - 1
h2d/col/RoundRect.hx

@@ -1,8 +1,16 @@
 package h2d.col;
 
+/**
+	A Collider representing the rectangle with the rounded edges, forming a 2D capsule.
+**/
 class RoundRect implements Collider {
-
+	/**
+		The horizontal position of the rectangle center.
+	**/
 	public var x : Float;
+	/**
+		The vertical position of the rectangle center.
+	**/
 	public var y : Float;
 	var ray : Float;
 	var dx : Float;
@@ -10,6 +18,14 @@ class RoundRect implements Collider {
 	var lenSq : Float;
 	var invLenSq : Float;
 
+	/**
+		Create a new RoundRect instance.
+		@param x The horizontal position of the rectangle center.
+		@param y The vertical position of the rectangle center.
+		@param w The width of the rectangle.
+		@param h The height of the rectangle.
+		@param rotation The rotation of the rectangle.
+	**/
 	public inline function new(x:Float,y:Float,w:Float,h:Float,rotation:Float) {
 		if( w < h ) {
 			var tmp = w;
@@ -30,6 +46,9 @@ class RoundRect implements Collider {
 	}
 
 	// distance segment
+	/**
+		Returns the squared distance of the Point `p` to the central segment of the capsule
+	**/
 	public inline function distanceCenterSq( p : Point ) {
 		var px = p.x - x;
 		var py = p.y - y;
@@ -48,14 +67,25 @@ class RoundRect implements Collider {
 		}
 	}
 
+	/**
+		Tests is given Point `p` is inside the capsule area.
+	**/
 	public inline function inside( p : Point ) {
 		return distanceCenterSq(p) - ray * ray < 0;
 	}
 
+	/**
+		Returns the distance of the Point `p` to the edge of the capsule.
+	**/
 	public inline function distance( p : Point ) {
 		return Math.sqrt(distanceCenterSq(p)) - ray;
 	}
 
+	/**
+		Returns an outwards normal of of the capsule edge in the direction of the Point `p`.
+
+		Normal points outwards regardless of the Point being inside or outside of the capsule.
+	**/
 	public inline function getNormalAt( p : Point ) {
 		var px = p.x - x;
 		var py = p.y - y;
@@ -73,6 +103,9 @@ class RoundRect implements Collider {
 		return new Point(px, py);
 	}
 
+	/**
+		Tests is given Point `p` is inside the capsule area.
+	**/
 	public function contains( p : Point ) {
 		return inside(p);
 	}

+ 58 - 1
h2d/col/Segment.hx

@@ -1,19 +1,59 @@
 package h2d.col;
 import hxd.Math;
 
+/**
+	A 2D line segment.
+	@see `h2d.Segments`
+**/
 class Segment {
 
+	/**
+		X starting position of the Segment.
+
+		Please use `Segment.setPoints` to modify this value.
+	**/
 	public var x : Float;
+	/**
+		Y starting position of the Segment.
+
+		Please use `Segment.setPoints` to modify this value.
+	**/
 	public var y : Float;
+	/**
+		The delta-value of X end position of the Segment relative to starting position.
+
+		Please use `Segment.setPoints` to modify this value.
+	**/
 	public var dx : Float;
+	/**
+		The delta-value of Y end position of the Segment relative to starting position.
+
+		Please use `Segment.setPoints` to modify this value.
+	**/
 	public var dy : Float;
+	/**
+		Squared length of the segment.
+
+		Please use `Segment.setPoints` to modify this value.
+	**/
 	public var lenSq : Float;
+	/**
+		Inverse of the Segments squared length.
+
+		Please use `Segment.setPoints` to modify this value.
+	**/
 	public var invLenSq : Float;
 
+	/**
+		Create a new Segment starting from Point `p1` and ending at Point `p2`.
+	**/
 	public inline function new( p1 : Point, p2 : Point ) {
 		setPoints(p1, p2);
 	}
 
+	/**
+		Sets Segment starting position at Point `p1` and ending position at Point `p2`.
+	**/
 	public inline function setPoints( p1 : Point, p2 : Point ) {
 		x = p1.x;
 		y = p1.y;
@@ -22,11 +62,17 @@ class Segment {
 		lenSq = dx * dx + dy * dy;
 		invLenSq = 1 / lenSq;
 	}
-
+	
+	/**
+		Returns a positive value if Point `p` is on the right side of the Segment axis and negative if it's on the left.
+	**/
 	public inline function side( p : Point ) {
 		return dx * (p.y - y) - dy * (p.x - x);
 	}
 
+	/**
+		Returns squared distance to the Segment as an infinite line to the Point `p`.
+	**/
 	public inline function distanceSq( p : Point ) {
 		var px = p.x - x;
 		var py = p.y - y;
@@ -45,10 +91,16 @@ class Segment {
 		}
 	}
 
+	/**
+		Returns distance from the Segment as an infinite line to the Point `p`.
+	**/
 	public inline function distance( p : Point ) {
 		return Math.sqrt(distanceSq(p));
 	}
 
+	/**
+		Projects Point `p` onto Segment. Returns position of intersection between Segment and line perpendicular to it going through Point `p`.
+	**/
 	public inline function project( p : Point ) : Point {
 		var px = p.x - x;
 		var py = p.y - y;
@@ -63,6 +115,11 @@ class Segment {
 		}
 	}
 
+	/**
+		Tests if Segments intersects given Ray `r`.
+		@param pt Optional Point instance to which intersection point is written. If not provided, returns new Point instance.
+		@returns A `Point` with intersection position or `null` if Segment and Ray do not intersect.
+	**/
 	public inline function lineIntersection( r : h2d.col.Ray, ?pt : Point ) {
 		if( r.side(new Point(x, y)) * r.side(new Point(x + dx, y + dy)) > 0 )
 			return null;

+ 33 - 3
h2d/col/Segments.hx

@@ -2,21 +2,39 @@ package h2d.col;
 import hxd.Math;
 
 /**
-	Another way to represent a Polygon. Segments must be connected.
-	This allows efficient distance calculus.
+	An abstract over the list of `Segment`s. Alternative representation of a polygon.
+	
+	Segments must be connected to form a complete polygonal shape.
+	Provides a more efficient distance calculus.
+
+	@see `h2d.Polygon`
 **/
 abstract Segments(Array<Segment>) from Array<Segment> to Array<Segment> {
 
+	/**
+		The underlying Array of segments.
+	**/
 	public var segments(get, never) : Array<Segment>;
 	inline function get_segments() return this;
+	/**
+		The amount of segments in the polygon.
+	**/
 	public var length(get, never) : Int;
 	inline function get_length() return this.length;
 
+	@:dox(hide)
 	public inline function iterator() {
 		return new hxd.impl.ArrayIterator(this);
 	}
 
-	public function containsPoint( p : Point, isConvex ) {
+	/**
+		Tests if Point `p` is inside this Segments.
+		@param p The Point to test against.
+		@param isConvex Use simplified collision test suited for convex polygons. Results are undefined if polygon is concave.
+
+		**Note**: Currently only convex check is implemented and using non-convex test results in an exception.
+	**/
+	public function containsPoint( p : Point, isConvex : Bool ) {
 		if( isConvex ) {
 			for( s in segments )
 				if( s.side(p) < 0 )
@@ -27,10 +45,16 @@ abstract Segments(Array<Segment>) from Array<Segment> to Array<Segment> {
 		return true;
 	}
 
+	/**
+		Converts this Segments to a Polygon.
+	**/
 	public function toPolygon() : Polygon {
 		return [for( s in segments ) new h2d.col.Point(s.x, s.y)];
 	}
 
+	/**
+		Projects Point `p` onto closest Segment in Segments and returns new Point with projected position.
+	**/
 	public function project( p : Point ) : Point {
 		var dmin = 1e20, smin = null;
 		for( s in segments ) {
@@ -43,6 +67,9 @@ abstract Segments(Array<Segment>) from Array<Segment> to Array<Segment> {
 		return smin.project(p);
 	}
 
+	/**
+		Returns squared distance from the Segments to the Point `p`.
+	**/
 	public function distanceSq( p : Point ) {
 		var dmin = 1e20;
 		for( s in segments ) {
@@ -52,6 +79,9 @@ abstract Segments(Array<Segment>) from Array<Segment> to Array<Segment> {
 		return dmin;
 	}
 
+	/**
+		Returns distance from the Segments to the Point `p`.
+	**/
 	public inline function distance( p : Point ) {
 		return Math.sqrt(distanceSq(p));
 	}

+ 35 - 2
h2d/col/Triangle.hx

@@ -1,15 +1,32 @@
 package h2d.col;
-
+/**
+	A simple triangle collider.
+**/
 class Triangle implements Collider {
 
 	static inline var UNDEF = 1.1315e-17;
 
+	/**
+		The triangle first corner.
+	**/
 	public var a : Point;
+	/**
+		The triangle second corner.
+	**/
 	public var b : Point;
+	/**
+		The triangle third corner.
+	**/
 	public var c : Point;
 	var area : Float;
 	var invArea : Float;
 
+	/**
+		Create a new Triangle collider.
+		@param a The first triangle corner.
+		@param b The second triangle corner.
+		@param c The third triangle corner.
+	**/
 	public inline function new( a : Point, b : Point, c : Point ) {
 		this.a = a;
 		this.b = b;
@@ -17,10 +34,18 @@ class Triangle implements Collider {
 		area = UNDEF;
 	}
 
+	/**
+		Returns a centroid of the Triangle.
+	**/
 	public inline function getCenter() {
 		return new Point((a.x + b.x + c.x) / 3, (a.y + b.y + c.y) / 3);
 	}
 
+	/**
+		Calculates and returns the triangle area.
+
+		Result is cached between `getArea` and `getInvArea` on first call and altering `a`, `b`, or `c` afterwards will lead to incorrect value.
+	**/
 	public inline function getArea() {
 		if( area == UNDEF ) {
 			area = ((a.y * b.x - a.x * b.y) + (b.y * c.x - b.x * c.y) + (c.y * a.x - c.x * a.y)) * -0.5;
@@ -29,13 +54,18 @@ class Triangle implements Collider {
 		return area;
 	}
 
+	/**
+		Calculates and returns the triangle area inverse.
+
+		Result is cached between `getArea` and `getInvArea` on first call and altering `a`, `b`, or `c` afterwards will lead to incorrect value.
+	**/
 	public inline function getInvArea() {
 		getArea();
 		return invArea;
 	}
 
 	/**
-		Calculate barycentric coordinates for the point p
+		Calculate barycentric coordinates for the point `p`
 	**/
 	public inline function barycentric( p : Point ) {
 		var area = getInvArea() * 0.5;
@@ -44,6 +74,9 @@ class Triangle implements Collider {
 		return new h3d.col.Point(1 - s - t, s, t);
 	}
 
+	/**
+		Tests if Point `p` is inside this Triangle.
+	**/
 	public function contains( p : Point ) {
 		var area = getInvArea() * 0.5;
 		var s = area * (a.y * c.x - a.x * c.y + (c.y - a.y) * p.x + (a.x - c.x) * p.y);

+ 142 - 36
h2d/col/Voronoi.hx

@@ -37,7 +37,7 @@ private class RBNode<T:RBNode<T>> {
 
 	public function new() {
 		this.root = null;
-    }
+	}
 
 	public function rbInsertSuccessor(node : T, successor : T) {
 		var parent;
@@ -129,7 +129,7 @@ private class RBNode<T:RBNode<T>> {
 			parent = node.rbParent;
 			}
 		this.root.rbRed = false;
-    }
+	}
 
 	public function rbRemoveNode(node:T) {
 		// >>> rhill 2011-05-27: Performance: cache previous/next nodes
@@ -256,7 +256,7 @@ private class RBNode<T:RBNode<T>> {
 			parent = parent.rbParent;
 		} while (!node.rbRed);
 		if (node != null) {node.rbRed = false;}
-    }
+	}
 
 	function rbRotateLeft(node:T) {
 		var p = node,
@@ -280,7 +280,7 @@ private class RBNode<T:RBNode<T>> {
 			p.rbRight.rbParent = p;
 			}
 		q.rbLeft = p;
-    }
+	}
 
 	function rbRotateRight(node:T) {
 		var p = node,
@@ -304,35 +304,53 @@ private class RBNode<T:RBNode<T>> {
 			p.rbLeft.rbParent = p;
 			}
 		q.rbRight = p;
-    }
+	}
 
 	public function getFirst(node:T) {
 		while(node.rbLeft != null)
 			node = node.rbLeft;
 		return node;
-    }
+	}
 
 	public function getLast(node:T) {
 		while( node.rbRight != null )
 			node = node.rbRight;
 		return node;
-    }
+	}
 }
 
+/**
+	The resulting cell inside the Voronoi diagram.
+**/
 class Cell {
 
+	/**
+		The unique ID/Index of the cell.
+	**/
 	public var id : Int;
+	/**
+		The source seed point of the cell.
+	**/
 	public var point : Point;
+	/**
+		The list of the edges of the cell.
+	**/
 	public var halfedges : Array<Halfedge>;
 	public var closeMe : Bool;
 
+	@:dox(hide) @:noCompletion
 	public function new(id, point) {
 		this.id = id;
 		this.point = point;
 		this.halfedges = [];
 		this.closeMe = false;
-    }
+	}
 
+	/**
+		Returns an enclosing circle collider of the Cell.
+
+		_Implementation note_: Not the best possible solution and may produce artifacts.
+	**/
 	public function getCircle() {
 		// still not the best enclosing circle
 		// would require implementing http://www.personal.kent.edu/~rmuhamma/Compgeometry/MyCG/CG-Applets/Center/centercli.htm for complete solution
@@ -353,6 +371,7 @@ class Cell {
 		return new Circle(p.x, p.y, Math.sqrt(r));
 	}
 
+	@:dox(hide) @:noCompletion
 	public function prepare() {
 		var halfedges = this.halfedges, iHalfedge = halfedges.length, edge;
 		// get rid of unused halfedges
@@ -378,7 +397,9 @@ class Cell {
 		return b.angle > a.angle ? 1 : (b.angle < a.angle ? -1 : 0);
 	}
 	
-	// Return a list of the neighbors
+	/**
+		Returns a list of the neighboring cells.
+	**/
 	public function getNeighbors() {
 		var neighbors = [],
 			iHalfedge = this.halfedges.length,
@@ -394,9 +415,11 @@ class Cell {
 				}
 			}
 		return neighbors;
-    }
+	}
 
-	// Return a list of the neighbor Indexes
+	/**
+		Returns a list of the neighbor Cell indexes.
+	**/
 	public function getNeighborIndexes() {
 		var neighbors = [],
 			iHalfedge = this.halfedges.length,
@@ -412,8 +435,11 @@ class Cell {
 				}
 			}
 		return neighbors;
-    }
+	}
 
+	/**
+		Returns a bounding box of the Cell.
+	**/
 	public function getBbox() {
 		var halfedges = this.halfedges,
 			iHalfedge = halfedges.length,
@@ -438,13 +464,15 @@ class Cell {
 			width: xmax-xmin,
 			height: ymax-ymin
 		};
-    }
+	}
 
-	// Return whether a point is inside, on, or outside the cell:
-	//   -1: point is outside the perimeter of the cell
-	//    0: point is on the perimeter of the cell
-	//    1: point is inside the perimeter of the cell
-	//
+	/**
+		Tests if given position is inside, on, or outside of the cell.
+		@returns
+		* -1: point is outside the perimeter of the cell
+		* 0: point is on the perimeter of the cell
+		* 1: point is inside the perimeter of the cell
+	**/
 	public function pointIntersection(x:Float, y:Float) {
 		// Check if point in polygon. Since all polygons of a Voronoi
 		// diagram are convex, then:
@@ -478,30 +506,66 @@ class Cell {
 
 }
 
+/**
+	The resulting edge inside the Voronoi diagram.
+**/
 class Edge {
-
+	/**
+		The unique ID/Index of the edge.
+	**/
 	public var id : Int;
+	/**
+		The left-hand seed point.
+	**/
 	public var lPoint : Point;
+	/**
+		The right-hand seed point.
+	**/
 	public var rPoint : Point;
+	/**
+		The left-hand cell along the edge.
+	**/
 	public var lCell : Null<Cell>;
+	/**
+		The right-hand cell along the edge.
+	**/
 	public var rCell : Null<Cell>;
+	/**
+		The first position of the edge segment.
+	**/
 	public var va : Null<Point>;
+	/**
+		The second position of the edge segment.
+	**/
 	public var vb : Null<Point>;
 
+	@:dox(hide) @:noCompletion
 	public function new(lPoint, rPoint) {
 		this.lPoint = lPoint;
 		this.rPoint = rPoint;
 		this.va = this.vb = null;
-    }
+	}
 }
 
-
+/**
+	The edge attached to a Voronoi `Cell`.
+**/
 class Halfedge {
 
+	/**
+		The seed Point of the Cell this edge is attached to.
+	**/
 	public var point : Point;
+	/**
+		The Edge this half-edge is attached to.
+	**/
 	public var edge : Edge;
+	/**
+		The perpendicular angle to the edge segment pointing in the direction of either neighboring Cell of the border.
+	**/
 	public var angle : Float;
 
+	@:dox(hide) @:noCompletion
 	public function new(edge, lPoint:Point, rPoint:Point) {
 		this.point = lPoint;
 		this.edge = edge;
@@ -525,25 +589,51 @@ class Halfedge {
 		}
 	}
 
+	/**
+		Returns the starting point of the edge segment.
+	**/
 	public inline function getStartpoint() {
 		return this.edge.lPoint == this.point ? this.edge.va : this.edge.vb;
-    }
+	}
 
+	/**
+		Returns the end point of the edge segment.
+	**/
 	public inline function getEndpoint() {
 		return this.edge.lPoint == this.point ? this.edge.vb : this.edge.va;
-    }
+	}
 
+	/**
+		Returns the neighboring Cell of this half-edge or null if it's a border edge.
+	**/
 	public inline function getTarget() {
 		return this.edge.lCell != null && this.edge.lCell.point != point ? this.edge.lCell : this.edge.rCell;
 	}
 
 }
 
+/**
+	The resulting diagram of the `Voronoi.compute`.
+**/
 class Diagram {
+	/**
+		The list of the generated cells.
+	**/
 	public var cells : Array<Cell>;
+	/**
+		The list of the diagram seed points.
+	**/
 	public var points : Array<Point>;
+	/**
+		The list of edges between diagram cells.
+	**/
 	public var edges : Array<Edge>;
+	/**
+		The duration it took to compute this diagram.
+	**/
 	public var execTime : Float;
+
+	@:dox(hide) @:noCompletion
 	public function new() {
 	}
 }
@@ -566,6 +656,11 @@ private class CircleEvent extends RBNode<CircleEvent> {
 	}
 }
 
+/**
+	A Steven Fortune's algorithm to compute Voronoi diagram from given set of Points and a bounding box.
+
+	The implementation is a port from JS library: https://github.com/gorhill/Javascript-Voronoi
+**/
 class Voronoi {
 
 	var epsilon : Float;
@@ -579,6 +674,9 @@ class Voronoi {
 	var firstCircleEvent : CircleEvent;
 	var pointCell : Map<Point,Cell>;
 
+	/**
+		Create a new Voronoi algorithm calculator.
+	**/
 	public function new( epsilon = 1e-9 ) {
 		this.epsilon = epsilon;
 		this.vertices = null;
@@ -586,8 +684,13 @@ class Voronoi {
 		this.cells = null;
 		this.beachsectionJunkyard = [];
 		this.circleEventJunkyard = [];
-    }
+	}
 
+	/**
+		Clean up the calculator from previous operation, and prepare for a new one.
+
+		Not required to be called manually, as it's invoked by `Voronoi.compute`.
+	**/
 	public function reset() {
 		if( this.beachline == null )
 			this.beachline = new RBTree<Beachsection>();
@@ -621,7 +724,7 @@ class Voronoi {
 		var v = new Point(x, y);
 		this.vertices.push(v);
 		return v;
-    }
+	}
 
 	// this create and add an edge to internal collection, and also create
 	// two halfedges which are added to each point's counterclockwise array
@@ -647,7 +750,7 @@ class Voronoi {
 		edge.vb = vb;
 		this.edges.push(edge);
 		return edge;
-    }
+	}
 
 	function setEdgeStartpoint(edge:Edge, lPoint, rPoint, vertex) {
 		if (edge.va == null && edge.vb == null) {
@@ -661,11 +764,11 @@ class Voronoi {
 		else {
 			edge.va = vertex;
 			}
-    }
+	}
 
 	function setEdgeEndpoint(edge, lPoint, rPoint, vertex) {
 		this.setEdgeStartpoint(edge, rPoint, lPoint, vertex);
-    }
+	}
 
 
 	// rhill 2011-06-02: A lot of Beachsection instanciations
@@ -750,7 +853,7 @@ class Voronoi {
 			}
 		// both parabolas have same distance to directrix, thus break point is midway
 		return (rfocx+lfocx)/2;
-    }
+	}
 
 	// calculate the right break point of a particular beach section,
 	// given a particular directrix
@@ -761,13 +864,13 @@ class Voronoi {
 			}
 		var point = arc.point;
 		return point.y == directrix ? point.x : Math.POSITIVE_INFINITY;
-    }
+	}
 
 	function detachBeachsection(beachsection) {
 		this.detachCircleEvent(beachsection); // detach potentially attached circle event
 		this.beachline.rbRemoveNode(beachsection); // remove from RB-tree
 		this.beachsectionJunkyard.push(beachsection); // mark for reuse
-    }
+	}
 
 	function removeBeachsection(beachsection:Beachsection) {
 		var circle = beachsection.circleEvent,
@@ -842,7 +945,7 @@ class Voronoi {
 		// adjacent to collapsed sections
 		this.attachCircleEvent(lArc);
 		this.attachCircleEvent(rArc);
-    }
+	}
 
 	function addBeachsection(point:Point) {
 		var x = point.x,
@@ -1015,7 +1118,7 @@ class Voronoi {
 			this.attachCircleEvent(rArc);
 			return;
 		}
-    }
+	}
 
 	function attachCircleEvent(arc:Beachsection) {
 		var lArc = arc.rbPrevious,
@@ -1104,7 +1207,7 @@ class Voronoi {
 		if (predecessor == null) {
 			this.firstCircleEvent = circleEvent;
 			}
-    }
+	}
 
 	function detachCircleEvent(arc:Beachsection) {
 		var circle = arc.circleEvent;
@@ -1116,7 +1219,7 @@ class Voronoi {
 			this.circleEventJunkyard.push(circle);
 			arc.circleEvent = null;
 		}
-    }
+	}
 
 	// ---------------------------------------------------------------------------
 	// Diagram completion methods
@@ -1397,7 +1500,7 @@ class Voronoi {
 			iLeft = 0;
 			while (iLeft < nHalfedges) {
 				va = halfedges[iLeft].getEndpoint();
-            	vz = halfedges[(iLeft+1) % nHalfedges].getStartpoint();
+				vz = halfedges[(iLeft+1) % nHalfedges].getStartpoint();
 				// if end point is not equal to start point, we need to add the missing
 				// halfedge(s) to close the cell
 				if (abs(va.x-vz.x)>=epsilon || abs(va.y-vz.y)>=epsilon) {
@@ -1509,6 +1612,9 @@ class Voronoi {
 	//   Voronoi points are kept client-side now, to allow
 	//   user to freely modify content. At compute time,
 	//   *references* to points are copied locally.
+	/**
+		Compute the Voronoi diagram based on given list of points and bounding box.
+	**/
 	public function compute(points:Array<Point>, bbox:Bounds) {
 		// to measure execution time
 		var startTime = haxe.Timer.stamp();

+ 20 - 0
h2d/filter/AbstractMask.hx

@@ -1,5 +1,6 @@
 package h2d.filter;
 
+@:dox(hide)
 class Hide extends Filter {
 
 	public var frame : Int;
@@ -19,6 +20,13 @@ class Hide extends Filter {
 
 }
 
+/**
+	A base class for filters that utilize separate Objects as a masking object.
+	
+	Not intended to be used directly.
+
+	Masking objects have a number of restrictions on them, see `AbstractMask.mask` for details.
+**/
 class AbstractMask extends Filter {
 
 	var hide : Hide;
@@ -26,7 +34,19 @@ class AbstractMask extends Filter {
 	var tmpMatrix : h2d.col.Matrix;
 	var obj : h2d.Object;
 	var bindCount : Int = 0;
+	/**
+		The Object contents of which serve as a mask to the filtered Object.
+		
+		Masking Objects have following limitations:
+		* It cannot be a parent of the filtered Object.
+		* It should not contain any filters.
+		* It should be present in the object tree and precede the Object it masks in the rendering order (rendered before it).
+		* Same masking Object cannot be used by multiple mask filters.
+	**/
 	public var mask(default, set) : h2d.Object;
+	/**
+		When enabled, masking Object will be visible to the user. Hidden otherwise. ( default : false )
+	**/
 	public var maskVisible(default, set) : Bool;
 
 	function new(mask) {

+ 23 - 0
h2d/filter/Ambient.hx

@@ -1,11 +1,34 @@
 package h2d.filter;
 
+/**
+	A ColorMatrix filer that applies color correction depending on the masked area.
+
+	Uses masked objects `red*alpha` channels to determine the transition from original color and transformed color.
+
+	_Hacking_: Through accessing color matrix shader directly via `@:privateAccess ambient.pass.shader.maskChannel`
+	it's possible to modify which channels affect the resulting transition value.
+
+	@see `ColorMatrix`
+**/
 class Ambient extends AbstractMask {
 
+	/**
+		The exponent of the mask color values that affects transition speed.
+	**/
 	public var power(get, set) : Float;
+
+	/**
+		Whether to apply ambient color correction inside masked (when enabled) area or outside of it (when disabled).
+	**/
 	public var invert(get, set) : Bool;
+
 	var pass : h3d.pass.ColorMatrix;
 
+	/**
+		Create new Ambient filter.
+		@param mask An `Object` that will be used for masking. See `AbstractMask.mask` for limitations.
+		@param m The color matrix that is applied to the area dictated by `Ambient.invert`.
+	**/
 	public function new( mask, ?m : h3d.Matrix ) {
 		pass = new h3d.pass.ColorMatrix(m);
 		super(mask);

+ 18 - 1
h2d/filter/Bloom.hx

@@ -1,11 +1,28 @@
 package h2d.filter;
 
+/**
+	Applies a bloom effect to the filtered Object.
+	Produces feathers to light areas in the objects.
+**/
 class Bloom extends Blur {
 
 	var bloom : h3d.pass.ScreenFx<h3d.shader.Bloom>;
+	/**
+		The bloom luminosity multiplier.
+	**/
 	public var amount(get, set) : Float;
+	/**
+		The bloom luminosity exponent.
+	**/
 	public var power(get, set) : Float;
 
+	/**
+		@param power The bloom luminosity exponent.
+		@param amount The bloom luminosity multiplier.
+		@param radius The bloom glow distance in pixels.
+		@param gain The bloom color intensity.
+		@param quality The sample count on each pixel as a tradeoff of speed/quality.
+	**/
 	public function new( power = 2., amount = 1., radius = 1., gain = 1., quality = 1. ) {
 		super(radius,gain,quality);
 		bloom = new h3d.pass.ScreenFx(new h3d.shader.Bloom());
@@ -31,4 +48,4 @@ class Bloom extends Blur {
 	}
 
 
-}
+}

+ 15 - 5
h2d/filter/Blur.hx

@@ -1,29 +1,39 @@
 package h2d.filter;
 
+/**
+	Utilizes the `h3d.pass.Blur` render pass to perform a blurring operation on the filtered object.
+**/
 class Blur extends Filter {
 
 	/**
-		See [h3d.pass.Blur.radius]
+		@see `h3d.pass.Blur.radius`
 	**/
 	public var radius(get, set) : Float;
 
 	/**
-		See [h3d.pass.Blur.linear]
+		@see `h3d.pass.Blur.linear`
 	**/
 	public var linear(get, set) : Float;
 
 	/**
-		See [h3d.pass.Blur.gain]
+		@see `h3d.pass.Blur.gain`
 	**/
 	public var gain(get, set) : Float;
 
 	/**
-		See [h3d.pass.Blur.quality]
+		@see `h3d.pass.Blur.quality`
 	**/
 	public var quality(get, set) : Float;
 
 	var pass : h3d.pass.Blur;
 
+	/**
+		Create a new Blur filter.
+		@param radius The blur distance in pixels.
+		@param gain The color gain when blurring.
+		@param quality The sample count on each pixel as a tradeoff of speed/quality.
+		@param linear Linear blur power. Set to 0 for gaussian blur.
+	**/
 	public function new( radius = 1., gain = 1., quality = 1., linear = 0. ) {
 		super();
 		smooth = true;
@@ -52,4 +62,4 @@ class Blur extends Filter {
 		return t;
 	}
 
-}
+}

+ 33 - 1
h2d/filter/ColorMatrix.hx

@@ -1,11 +1,40 @@
 package h2d.filter;
 
+/**
+	Applies a color correction filter based on the provided matrix.
+
+	Matrix values are as following:
+	```
+	     red        green      blue       alpha
+	[   redMult,   redMult,   redMult,   redMult ]
+	[ greenMult, greenMult, greenMult, greenMult ]
+	[  blueMult,  blueMult,  blueMult,  blueMult ]
+	[ alphaMult, alphaMult, alphaMult, alphaMult ]
+	```
+	An identity matrix will result in an unmodified colors:
+	```
+	[1, 0, 0, 0]
+	[0, 1, 0, 0]
+	[0, 0, 1, 0]
+	[0, 0, 0, 1]
+	```
+	
+	@see `Ambient`
+**/
 class ColorMatrix extends Filter {
 
+	/**
+		The matrix used to apply color correction.
+	**/
 	public var matrix(get, set) : h3d.Matrix;
 
 	var pass : h3d.pass.ColorMatrix;
 
+	/**
+		Create a new ColorMatrix filter.
+
+		@param m The matrix used to modify the resulting colors.
+	**/
 	public function new( ?m : h3d.Matrix ) {
 		super();
 		pass = new h3d.pass.ColorMatrix(m);
@@ -21,6 +50,9 @@ class ColorMatrix extends Filter {
 		return h2d.Tile.fromTexture(tout);
 	}
 
+	/**
+		Returns a ColorMatrix filter which results in a grayscale image (0 saturation).
+	**/
 	public static function grayed() {
 		var m = new h3d.Matrix();
 		m.identity();
@@ -28,4 +60,4 @@ class ColorMatrix extends Filter {
 		return new ColorMatrix(m);
 	}
 
-}
+}

+ 26 - 1
h2d/filter/Displacement.hx

@@ -1,14 +1,39 @@
 package h2d.filter;
 import hxd.Math;
 
+/**
+	Applies a normal map to the filtered Object in order to displace pixels.
+
+	Uses red and green channels to displaces horizontal and vertical axes accordingly.
+**/
 class Displacement extends Filter {
 
+	/**
+		The normal map used for displacement lookup.
+	**/
 	public var normalMap : h2d.Tile;
+	/**
+		Horizontal displacement distance in pixels.
+	**/
 	public var dispX : Float;
+	/**
+		Vertical displacement distance in pixels.
+	**/
 	public var dispY : Float;
+	/**
+		When enabled, the displacement map will wrap around when lookup reaches its edges.
+		Otherwise out-of-bounds values are clamped to the border.
+	**/
 	public var wrap(default, set) : Bool;
 	var disp = new h3d.pass.ScreenFx(new h3d.shader.Displacement());
 
+	/**
+		Create a new displacement filter.
+		@param normalMap The normal map used for displacement lookup.
+		@param dispX Horizontal displacement distance in pixels.
+		@param dispY Vertical displacement distance in pixels.
+		@param wrap Wrap normal map around when lookup UV goes out of bounds.
+	**/
 	public function new( normalMap : h2d.Tile, dispX : Float = 5., dispY = 5., wrap = true ) {
 		super();
 		this.normalMap = normalMap;
@@ -41,4 +66,4 @@ class Displacement extends Filter {
 		return h2d.Tile.fromTexture(out);
 	}
 
-}
+}

+ 20 - 0
h2d/filter/DropShadow.hx

@@ -1,12 +1,32 @@
 package h2d.filter;
 import hxd.Math;
 
+/**
+	Adds a soft shadow to the filtered Object.
+**/
 class DropShadow extends Glow {
 
+	/**
+		The offset distance of the shadow in the direction of `DropShadow.angle`.
+	**/
 	public var distance : Float;
+	/**
+		The shadow offset direction angle.
+	**/
 	public var angle : Float;
 	var alphaPass = new h3d.mat.Pass("");
 
+	/**
+		Create a new Shadow filter.
+		@param distance The offset of the shadow in the `angle` direction.
+		@param angle Shadow offset direction angle.
+		@param color The color of the shadow.
+		@param alpha Transparency value of the shadow.
+		@param radius The shadow glow distance in pixels.
+		@param gain The shadow color intensity.
+		@param quality The sample count on each pixel as a tradeoff of speed/quality.
+		@param smoothColor Produce gradient shadow when enabled, otherwise creates hard shadow without smoothing.
+	**/
 	public function new( distance : Float = 4., angle : Float = 0.785, color : Int = 0, alpha = 1., radius : Float = 1., gain : Float = 1, quality = 1., smoothColor = false ) {
 		super(color, alpha, radius, gain, quality, smoothColor);
 		this.distance = distance;

+ 51 - 1
h2d/filter/Filter.hx

@@ -2,12 +2,41 @@ package h2d.filter;
 
 /**
 	The base filter class, you can extend it in order to define your own filters, although ShaderFilter will be the most straightforward way to define simple custom filter.
+
+	Keep in mind that filters use internal Object resolution to render its content, hence scaling of the filtered object would not increase the rendering resolution.
+	For example, 20x20px `Bitmap` with `scale = 2` will render onto 20x20 filter texture if filter is attached to it directly,
+	but if filter is attached to the parent of that bitmap, filter will render 40x40 texture.  
+	Another thing to be aware of, is that `Scene.scaleMode` does not affect filter resolution either,
+	and upscaling contents with `scaleMode` would not upscale the resolution of filtered content.
+
+	Filters limit their render area dictated by bound object boundaries, `Filter.autoBounds` and `Filter.boundsExtend` variables and `Filter.getBounds` method.
+	See their respective docs for details.
+
+	For optimization purposes, rendering boundaries are clipped by scene viewport and nothing will be rendered offscreen.
 **/
 class Filter {
 
+	/**
+		When enabled, rendering bounds of the filter will be expanded by `Filter.boundsExtend` in all directions.
+		Otherwise filter should provide custom bounds through `Filter.getBounds` call.  
+		Default : true.
+	**/
 	public var autoBounds = true;
+	/**
+		Rendering texture boundaries extent. Increases the rendering area by twice the `Filter.boundsExtend` value.  
+		Automatically applied to object bounds when `autoBounds = true` or `Filter.getBounds` is not overridden.  
+		Does not affect boundaries when `autoBounds = true` and `boundsExtend` is less than 0.
+	**/
 	public var boundsExtend : Float = 0.;
+	/**
+		When enabled, some filters will use bilinear filtering on temporary textures.  
+		Does not affect the majority of filters.
+		@see `AbstractMask`
+	**/
 	public var smooth = false;
+	/**
+		When filter is disabled, attached object will render as usual.
+	**/
 	@:isVar public var enable(get,set) = true;
 
 	function new() {
@@ -16,15 +45,33 @@ class Filter {
 	function get_enable() return enable;
 	function set_enable(v) return enable = v;
 
+	/**
+		Used to sync data for rendering.
+	**/
 	public function sync( ctx : RenderContext, s : Object ) {
 	}
 
+	/**
+		Sent when filter is bound to an Object `s`.
+		If Object was not yet allocated, method will be called when it's added to allocated Scene.
+	**/
 	public function bind( s : Object ) {
 	}
 
+	/**
+		Sent when filter was unbound from an Object `s`.
+		Method won't be called if Object was not yet allocated.
+	**/
 	public function unbind( s : Object ) {
 	}
 
+	/**
+		Method should populate `bounds` with rendering boundaries of the Filter for Object `s`.
+		Initial `bounds` contents are undefined and it's recommended to either clear them or call `s.getBounds(s, bounds)`.
+		Only used when `Filter.autoBounds` is `false`.
+		By default uses given Object bounds and extends them with `Filter.boundsExtend`.
+		Compared to `autoBounds = true`, negative `boundsExtend` is still applied, causing rendering area to shrink.
+	**/
 	public function getBounds( s : Object, bounds : h2d.col.Bounds ) {
 		s.getBounds(s, bounds);
 		bounds.xMin -= boundsExtend;
@@ -33,8 +80,11 @@ class Filter {
 		bounds.yMax += boundsExtend;
 	}
 
+	/**
+		Renders the filter onto Texture in `input` Tile.
+	**/
 	public function draw( ctx : RenderContext, input : h2d.Tile ) {
 		return input;
 	}
 
-}
+}

+ 24 - 0
h2d/filter/Glow.hx

@@ -1,12 +1,36 @@
 package h2d.filter;
 
+/**
+	Adds a glow backdrop to the filtered Object.
+**/
 class Glow extends Blur {
 
+	/**
+		The color of the glow.
+	**/
 	public var color : Int;
+	/**
+		Transparency value of the glow.
+	**/
 	public var alpha : Float;
+	/**
+		Subtracts the original image from the glow output when enabled.
+	**/
 	public var knockout : Bool;
+	/**
+		Produce gradient glow when enabled, otherwise creates hard glow without smoothing.
+	**/
 	public var smoothColor : Bool;
 
+	/**
+		Create new Glow filter.
+		@param color The color of the glow.
+		@param alpha Transparency value of the glow.
+		@param radius The glow distance in pixels.
+		@param gain The glow color intensity.
+		@param quality The sample count on each pixel as a tradeoff of speed/quality.
+		@param smoothColor Produce gradient glow when enabled, otherwise creates hard glow without smoothing.
+	**/
 	public function new( color : Int = 0xFFFFFF, alpha = 1., radius = 1., gain = 1., quality = 1., smoothColor = false ) {
 		super(radius, gain, quality);
 		this.color = color;

+ 24 - 0
h2d/filter/Group.hx

@@ -1,9 +1,25 @@
 package h2d.filter;
 
+/**
+	Applies an array of Filters to a single Object with several limitations.
+
+	* If all filters in the Group are disabled - `Filter.enable` will report `false` even if Group itself is enabled.  
+	* `Filter.boundsExtend` and `Filter.autoBounds` are automatically managed by Group instance.
+	* `boundsExtend` is a sum of all filter extends and `autoBounds` enabled only when all filters have it enabled.
+
+	When `autoBounds` is disabled, bounds are a result of calling `Filter.getBounds` on children filters, but most likely
+	will contain only the bounds filled by last filter, because `Object.getBounds` clears the `Bounds` instance.
+
+	Ensure that all relevant filters are added to Group prior binding it to any Object. Behavior is undefined otherwise.
+**/
 class Group extends Filter {
 
 	var filters : Array<Filter>;
 
+	/**
+		Create a new filter Group.
+		@param filters Optional list of the Filters bound to the group.
+	**/
 	public function new( ?filters : Array<Filter> ) {
 		super();
 		this.filters = filters == null ? [] : filters;
@@ -15,10 +31,18 @@ class Group extends Filter {
 		return false;
 	}
 	
+	/**
+		Adds new Filter `f` to the Group.  
+		Due to implementation specifics, if Group was already bound, new filters won't receive a `bind` call.
+	**/
 	public function add( f : Filter ) {
 		filters.push(f);
 	}
 
+	/**
+		Removes the Filter `f` from the Group.
+		Due to implementation specifics, removed filter won't receive an `unbind` call even if it was bound previously.
+	**/
 	public function remove( f : Filter ) {
 		return filters.remove(f);
 	}

+ 13 - 0
h2d/filter/Mask.hx

@@ -22,12 +22,25 @@ private class MaskShader extends h3d.shader.ScreenShader {
 
 }
 
+/**
+	Performs an arbitrary shape masking of the filtered Object.
 
+	@see `AbstractMask`
+**/
 class Mask extends AbstractMask {
 
 	var pass : h3d.pass.ScreenFx<MaskShader>;
+	/**
+		Enables masking Object alpha merging. Otherwise causes unsmoothed masking of non-zero alpha areas.
+	**/
 	public var smoothAlpha(get, set) : Bool;
 
+	/**
+		Create new Mask filter.
+		@param mask An `Object` that will be used for masking. See `AbstractMask.mask` for limitations.
+		@param maskVisible When enabled, masking `Object` will be visible. Hidden otherwise.
+		@param smoothAlpha Enables masking Object alpha merging. Otherwise causes unsmoothed masking of non-zero alpha areas.
+	**/
 	public function new(mask, maskVisible=false, smoothAlpha=false) {
 		super(mask);
 		pass = new h3d.pass.ScreenFx(new MaskShader());

+ 6 - 0
h2d/filter/Nothing.hx

@@ -1,7 +1,13 @@
 package h2d.filter;
 
+/**
+	A filter that renders nothing.
+**/
 class Nothing extends Filter {
 
+	/**
+		Create a new Nothing filter.
+	**/
 	public function new() {
 		super();
 	}

+ 30 - 0
h2d/filter/Outline.hx

@@ -1,14 +1,44 @@
 package h2d.filter;
 
+/**
+	Provides a solid color outline to the filtered object by utilizing `h3d.pass.Outline` render pass.
+**/
 class Outline extends Filter {
+	/**
+		The width of the outline.
+		@see `h3d.pass.Outline.size`
+	**/
 	public var size(get, set) : Float;
+	/**
+		The color of the outline.
+		@see `h3d.pass.Outline.color`
+	**/
 	public var color(get, set) : Int;
+	/**
+		Represents sample count with quality/speed tradeoff.
+		Larger value leads to more samples and more accurate outline in exchange to calculation speed.
+		@see `h3d.pass.Outline.quality`
+	**/
 	public var quality(get, set) : Float;
+	/**
+		Premultiplies the resulting color with its alpha when enabled.
+		@see `h2d.pass.Outline.multiplyAlpha`
+	**/
 	public var multiplyAlpha(get, set) : Bool;
+	/**
+		The transparency of the outline.
+	**/
 	public var alpha(get, set) : Float;
 
 	var pass : h3d.pass.Outline;
 
+	/**
+		Create a new Outline filter.
+		@param size Width of the outline.
+		@param color The color of the outline.
+		@param quality The sample count with quality/speed tradeoff.
+		@param multiplyAlpha Enable alpha premultiplying of the resulting color.
+	**/
 	public function new(size = 4.0, color = 0x000000, quality = 0.3, multiplyAlpha = true) {
 		super();
 		smooth = true;

+ 44 - 0
h2d/filter/Shader.hx

@@ -1,12 +1,56 @@
 package h2d.filter;
 
+/**
+	The base class for simple filters that don't need specialized render passes and rely completely on the shaders.
+
+	Provides an easy interface to implement custom filters without going too deep into filter rendering process with render passes.
+
+	Compatible shaders should extend from `h3d.shader.ScreenShader` and contain an input texture uniform, as well as assign `pixelColor` in fragment shader.
+
+	Sample of a simple custom filter:
+	```haxe
+	class InvertColorShader extends h3d.shader.ScreenShader {
+		static var SRC = {
+			@param var texture : Sampler2D;
+			
+			function fragment() {
+				var pixel : Vec4 = texture.get(calculatedUV);
+				// Premultiply alpha to ensure correct transparency.
+				pixelColor = vec4((1. - pixel.rgb) * pixel.a, pixel.a);
+				// Some other filters directly assign `output.color` and fetch from `input.uv`.
+				// While it will work, it does not work well when multiple shaders in one filter are involved.
+				// In this case use `calculatedUV` and `pixelColor`.
+			}
+		}
+	}
+
+	// When initializing
+	// Second argument should point at Sampler2D that will take in the texture with contents filter should modify.
+	myObj.filter = new h2d.filter.Shader<InvertColorShader>(new InvertColorShader(), "texture");
+	```
+**/
 class Shader< T:h3d.shader.ScreenShader > extends Filter {
 
+	/**
+		The assigned shader instance.
+		Can be accessed to modify shader uniforms.
+	**/
 	public var shader(get, never) : T;
+	/**
+		ScreenFX pass that will render the filter.
+	**/
 	public var pass : h3d.pass.ScreenFx<T>;
+	/**
+		When enabled, sampling on the input texture will use nearest neighbor algorithm.
+	**/
 	public var nearest : Bool;
 	var textureParam : String;
 
+	/**
+		Create new shader filter.
+		@param shader The shader instance that will be used for rendering.
+		@param textureParam The name of `Sampler2D` in the shader to which input texture will be assigned. Should be present in the shader.
+	**/
 	public function new( shader : T, textureParam = "texture" ) {
 		super();
 		var found = false;

+ 69 - 1
h2d/impl/PointApi.hx

@@ -1,23 +1,66 @@
 package h2d.impl;
 
-interface GenPointApi<Point,Unit> {
+/**
+	A base common API interface for the points to validate API parity between 3D and 2D classes.
 
+	Intended for internal usage. Use `-D apicheck` compilation flag to enable parity validation.
+**/
+interface GenPointApi<Point,Unit> {
+	/**
+		Returns a copy of the Point/
+	**/
 	function clone() : Point;
+	/**
+		Copy the position data from a given Point `p` to this Point.
+	**/
 	function load( p : Point ) : Void;
+	/**
+		Returns a new Point with the sum of this Point and a given Point `p`.
+	**/
 	function add( p : Point ) : Point;
+	/**
+		Returns a new Point with the results of a subtraction of a given Point `p` from this Point.
+	**/
 	function sub( p : Point ) : Point;
+	/**
+		Returns a new Point with the position of this Point multiplied by scalar `v`.
+	**/
 	function multiply( v : Unit ) : Point;
 
+	/**
+		Multiplies position of this Point by scalar `v`.
+	**/
 	function scale( v : Unit ) : Void;
+	/**
+		Returns a squared length of the Point.
+	**/
 	function lengthSq() : Unit;
+	/**
+		Return the length of the Point.
+	**/
 	function length() : Float;
 
+	/**
+		Returns the distance between this Point and given Point `p`.
+	**/
 	function distance( p : Point ) : Float;
+	/**
+		Returns a squared distance between this Point and given Point `p`.
+	**/
 	function distanceSq( p : Point ) : Unit;
 
+	/**
+		Tests if this Point position equals to the position of an `other` Point.
+	**/
 	function equals( other : Point ) : Bool;
+	/**
+		Returns a dot product between this Point and given Point `p`.
+	**/
 	function dot( p : Point ) : Unit;
 
+	/**
+		Returns a human-readable string representation of the Point.
+	**/
 	function toString() : String;
 
 	// function set(x=0., y=0., z=0.) : Void;
@@ -26,18 +69,43 @@ interface GenPointApi<Point,Unit> {
 
 }
 
+/**
+	A common API interface for the floating-point Points to validate API parity between 3D and 2D classes.
+
+	Intended for internal usage. Use `-D apicheck` compilation flag to enable parity validation.
+**/
 interface PointApi<Point,M> extends GenPointApi<Point,Float> {
 
+	/**
+		Sets this Point position to a result of linear interpolation between Points `p1` and `p2` at the interpolant position `k`.
+	**/
 	function lerp( p1 : Point, p2 : Point, k : Float ) : Void;
 
+	/**
+		Normalizes the Point.
+	**/
 	function normalize() : Void;
+	/**
+		Returns a new Point with the normalized values of this Point.
+	**/
 	function normalized() : Point;
+	/**
+		Applies a given Matrix `m` transformation to this Point position.
+	**/
 	function transform( m : M ) : Void;
+	/**
+		Returns a new Point with a result of applying a Matrix `m` to this Point position.
+	**/
 	function transformed( m : M ) : Point;
 	// function transform3x3( m : Matrix ) : Void (3D)
 	// function transform2x2( m : Matrix ) : Void (2D)
 
 }
 
+/**
+	A common API interface for the integer Points to validate API parity between 3D and 2D classes.
+
+	Intended for internal usage. Use `-D apicheck` compilation flag to enable parity validation.
+**/
 interface IPointApi<Point> extends GenPointApi<Point,Int> {
 }

+ 2 - 2
hxd/Key.hx

@@ -133,7 +133,7 @@ class Key {
 	public static inline var MOUSE_BACK = 3;
 	public static inline var MOUSE_FORWARD = 4;
 	/**
-	 * Mouse wheel does not have an off signal, and should be checked only trough `isPressed` method.
+	 * Mouse wheel does not have an off signal, and should be checked only through `isPressed` method.
 	 * Note that there may be multiple wheel scrolls between 2 frames, and to receive more accurate
 	 * results, it is recommended to directly listen to wheel events which also provide OS-generated wheel delta value.
 	 * See `Interactive.onWheel` for per-interactive events. For scene-based see `Scene.addEventListener`
@@ -141,7 +141,7 @@ class Key {
 	 */
 	public static inline var MOUSE_WHEEL_UP = 5;
 	/**
-	 * Mouse wheel does not have an off signal, and should be checked only trough `isPressed` method.
+	 * Mouse wheel does not have an off signal, and should be checked only through `isPressed` method.
 	 * Note that there may be multiple wheel scrolls between 2 frames, and to receive more accurate
 	 * results, it is recommended to directly listen to wheel events which also provide OS-generated wheel delta value.
 	 * See `Interactive.onWheel` for per-interactive events. For scene-based see `Scene.addEventListener`

Daži faili netika attēloti, jo izmaiņu fails ir pārāk liels