forked from LeenkxTeam/LNXSDK
		
	
		
			
				
	
	
		
			177 lines
		
	
	
		
			6.4 KiB
		
	
	
	
		
			Haxe
		
	
	
	
	
	
			
		
		
	
	
			177 lines
		
	
	
		
			6.4 KiB
		
	
	
	
		
			Haxe
		
	
	
	
	
	
| package kha;
 | |
| 
 | |
| import kha.math.FastMatrix3;
 | |
| 
 | |
| class TargetRectangle {
 | |
| 	public var x: Float;
 | |
| 	public var y: Float;
 | |
| 	public var width: Float;
 | |
| 	public var height: Float;
 | |
| 	public var scaleFactor: Float;
 | |
| 	public var rotation: ScreenRotation;
 | |
| 
 | |
| 	public inline function new(x: Float, y: Float, w: Float, h: Float, s: Float, r: ScreenRotation) {
 | |
| 		this.x = x;
 | |
| 		this.y = y;
 | |
| 		this.width = w;
 | |
| 		this.height = h;
 | |
| 		this.scaleFactor = s;
 | |
| 		this.rotation = r;
 | |
| 	}
 | |
| }
 | |
| 
 | |
| class Scaler {
 | |
| 	public static function targetRect(width: Int, height: Int, destinationWidth: Int, destinationHeight: Int, rotation: ScreenRotation): TargetRectangle {
 | |
| 		var scalex: Float;
 | |
| 		var scaley: Float;
 | |
| 		var scalew: Float;
 | |
| 		var scaleh: Float;
 | |
| 		var scale: Float;
 | |
| 		switch (rotation) {
 | |
| 			case ScreenRotation.RotationNone:
 | |
| 				if (width / height > destinationWidth / destinationHeight) {
 | |
| 					scale = destinationWidth / width;
 | |
| 					scalew = width * scale;
 | |
| 					scaleh = height * scale;
 | |
| 					scalex = 0;
 | |
| 					scaley = (destinationHeight - scaleh) * 0.5;
 | |
| 				}
 | |
| 				else {
 | |
| 					scale = destinationHeight / height;
 | |
| 					scalew = width * scale;
 | |
| 					scaleh = height * scale;
 | |
| 					scalex = (destinationWidth - scalew) * 0.5;
 | |
| 					scaley = 0;
 | |
| 				}
 | |
| 			case ScreenRotation.Rotation90:
 | |
| 				if (width / height > destinationHeight / destinationWidth) {
 | |
| 					scale = destinationHeight / width;
 | |
| 					scalew = width * scale;
 | |
| 					scaleh = height * scale;
 | |
| 					scalex = (destinationWidth - scaleh) * 0.5 + scaleh;
 | |
| 					scaley = 0;
 | |
| 				}
 | |
| 				else {
 | |
| 					scale = destinationWidth / height;
 | |
| 					scalew = width * scale;
 | |
| 					scaleh = height * scale;
 | |
| 					scalex = 0 + scaleh;
 | |
| 					scaley = (destinationHeight - scalew) * 0.5;
 | |
| 				}
 | |
| 			case ScreenRotation.Rotation180:
 | |
| 				if (width / height > destinationWidth / destinationHeight) {
 | |
| 					scale = destinationWidth / width;
 | |
| 					scalew = width * scale;
 | |
| 					scaleh = height * scale;
 | |
| 					scalex = 0 + scalew;
 | |
| 					scaley = (destinationHeight - scaleh) * 0.5 + scaleh;
 | |
| 				}
 | |
| 				else {
 | |
| 					scale = destinationHeight / height;
 | |
| 					scalew = width * scale;
 | |
| 					scaleh = height * scale;
 | |
| 					scalex = (destinationWidth - scalew) * 0.5 + scalew;
 | |
| 					scaley = 0 + scaleh;
 | |
| 				}
 | |
| 			case ScreenRotation.Rotation270:
 | |
| 				if (width / height > destinationHeight / destinationWidth) {
 | |
| 					scale = destinationHeight / width;
 | |
| 					scalew = width * scale;
 | |
| 					scaleh = height * scale;
 | |
| 					scalex = (destinationWidth - scaleh) * 0.5;
 | |
| 					scaley = 0 + scalew;
 | |
| 				}
 | |
| 				else {
 | |
| 					scale = destinationWidth / height;
 | |
| 					scalew = width * scale;
 | |
| 					scaleh = height * scale;
 | |
| 					scalex = 0;
 | |
| 					scaley = (destinationHeight - scalew) * 0.5 + scalew;
 | |
| 				}
 | |
| 		}
 | |
| 		return new TargetRectangle(scalex, scaley, scalew, scaleh, scale, rotation);
 | |
| 	}
 | |
| 
 | |
| 	public static function transformXDirectly(x: Int, y: Int, sourceWidth: Int, sourceHeight: Int, destinationWidth: Int, destinationHeight: Int,
 | |
| 			rotation: ScreenRotation): Int {
 | |
| 		var targetRect = targetRect(sourceWidth, sourceHeight, destinationWidth, destinationHeight, rotation);
 | |
| 		switch (targetRect.rotation) {
 | |
| 			case ScreenRotation.RotationNone:
 | |
| 				return Std.int((x - targetRect.x) / targetRect.scaleFactor);
 | |
| 			case ScreenRotation.Rotation90:
 | |
| 				return Std.int((y - targetRect.y) / targetRect.scaleFactor);
 | |
| 			case ScreenRotation.Rotation180:
 | |
| 				return Std.int((targetRect.x - x) / targetRect.scaleFactor);
 | |
| 			case ScreenRotation.Rotation270:
 | |
| 				return Std.int((targetRect.y - y) / targetRect.scaleFactor);
 | |
| 		}
 | |
| 	}
 | |
| 
 | |
| 	/**
 | |
| 	 * Transform the X value from the given position in the source to a position in the destination canvas.
 | |
| 	 *
 | |
| 	 * @param x					The X position.
 | |
| 	 * @param y					The Y position.
 | |
| 	 * @param source			The source image.
 | |
| 	 * @param destination		The destination canvas.
 | |
| 	 * @param rotation			The screen rotation.
 | |
| 	 */
 | |
| 	public static function transformX(x: Int, y: Int, source: Image, destination: Canvas, rotation: ScreenRotation): Int {
 | |
| 		return transformXDirectly(x, y, source.width, source.height, destination.width, destination.height, rotation);
 | |
| 	}
 | |
| 
 | |
| 	public static function transformYDirectly(x: Int, y: Int, sourceWidth: Int, sourceHeight: Int, destinationWidth: Int, destinationHeight: Int,
 | |
| 			rotation: ScreenRotation): Int {
 | |
| 		var targetRect = targetRect(sourceWidth, sourceHeight, destinationWidth, destinationHeight, rotation);
 | |
| 		switch (targetRect.rotation) {
 | |
| 			case ScreenRotation.RotationNone:
 | |
| 				return Std.int((y - targetRect.y) / targetRect.scaleFactor);
 | |
| 			case ScreenRotation.Rotation90:
 | |
| 				return Std.int((targetRect.x - x) / targetRect.scaleFactor);
 | |
| 			case ScreenRotation.Rotation180:
 | |
| 				return Std.int((targetRect.y - y) / targetRect.scaleFactor);
 | |
| 			case ScreenRotation.Rotation270:
 | |
| 				return Std.int((x - targetRect.x) / targetRect.scaleFactor);
 | |
| 		}
 | |
| 	}
 | |
| 
 | |
| 	/**
 | |
| 	 * Transform the Y value from the given position in the source to a position in the destination canvas.
 | |
| 	 *
 | |
| 	 * @param x					The X position.
 | |
| 	 * @param y					The Y position.
 | |
| 	 * @param source			The source image.
 | |
| 	 * @param destination		The destination canvas.
 | |
| 	 * @param rotation			The screen rotation.
 | |
| 	 */
 | |
| 	public static function transformY(x: Int, y: Int, source: Image, destination: Canvas, rotation: ScreenRotation): Int {
 | |
| 		return transformYDirectly(x, y, source.width, source.height, destination.width, destination.height, rotation);
 | |
| 	}
 | |
| 
 | |
| 	public static function scale(source: Image, destination: Canvas, rotation: ScreenRotation): Void {
 | |
| 		var g = destination.g2;
 | |
| 		g.pushTransformation(getScaledTransformation(source.width, source.height, destination.width, destination.height, rotation));
 | |
| 		g.color = Color.White;
 | |
| 		g.opacity = 1;
 | |
| 		g.drawImage(source, 0, 0);
 | |
| 		g.popTransformation();
 | |
| 	}
 | |
| 
 | |
| 	public static function getScaledTransformation(width: Int, height: Int, destinationWidth: Int, destinationHeight: Int,
 | |
| 			rotation: ScreenRotation): FastMatrix3 {
 | |
| 		var rect = targetRect(width, height, destinationWidth, destinationHeight, rotation);
 | |
| 		var sf = rect.scaleFactor;
 | |
| 		var transformation = new FastMatrix3(sf, 0, rect.x, 0, sf, rect.y, 0, 0, 1);
 | |
| 		switch (rotation) {
 | |
| 			case RotationNone:
 | |
| 			case Rotation90:
 | |
| 				transformation = transformation.multmat(FastMatrix3.rotation(Math.PI / 2));
 | |
| 			case Rotation180:
 | |
| 				transformation = transformation.multmat(FastMatrix3.rotation(Math.PI));
 | |
| 			case Rotation270:
 | |
| 				transformation = transformation.multmat(FastMatrix3.rotation(Math.PI * 3 / 2));
 | |
| 		}
 | |
| 		return transformation;
 | |
| 	}
 | |
| }
 |