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;
|
|
}
|
|
}
|