Merge branch 'develop' into 8.3.0-Dev
This commit is contained in:
@@ -149,7 +149,7 @@ class NativeCFFI
|
||||
|
||||
@:cffi private static function lime_font_render_glyphs(handle:Dynamic, indices:Dynamic, data:Dynamic):Dynamic;
|
||||
|
||||
@:cffi private static function lime_font_set_size(handle:Dynamic, size:Int):Void;
|
||||
@:cffi private static function lime_font_set_size(handle:Dynamic, size:Int, dpi:Int):Void;
|
||||
|
||||
@:cffi private static function lime_gamepad_add_mappings(mappings:Dynamic):Void;
|
||||
|
||||
@@ -439,7 +439,7 @@ class NativeCFFI
|
||||
"lime_font_render_glyph", "oioo", false));
|
||||
private static var lime_font_render_glyphs = new cpp.Callable<cpp.Object->cpp.Object->cpp.Object->cpp.Object>(cpp.Prime._loadPrime("lime",
|
||||
"lime_font_render_glyphs", "oooo", false));
|
||||
private static var lime_font_set_size = new cpp.Callable<cpp.Object->Int->cpp.Void>(cpp.Prime._loadPrime("lime", "lime_font_set_size", "oiv", false));
|
||||
private static var lime_font_set_size = new cpp.Callable<cpp.Object->Int->Int->cpp.Void>(cpp.Prime._loadPrime("lime", "lime_font_set_size", "oiiv", false));
|
||||
private static var lime_gamepad_add_mappings = new cpp.Callable<cpp.Object->cpp.Void>(cpp.Prime._loadPrime("lime", "lime_gamepad_add_mappings", "ov",
|
||||
false));
|
||||
private static var lime_gamepad_get_device_guid = new cpp.Callable<Int->cpp.Object>(cpp.Prime._loadPrime("lime", "lime_gamepad_get_device_guid", "io",
|
||||
@@ -672,7 +672,7 @@ class NativeCFFI
|
||||
private static var lime_font_outline_decompose = CFFI.load("lime", "lime_font_outline_decompose", 2);
|
||||
private static var lime_font_render_glyph = CFFI.load("lime", "lime_font_render_glyph", 3);
|
||||
private static var lime_font_render_glyphs = CFFI.load("lime", "lime_font_render_glyphs", 3);
|
||||
private static var lime_font_set_size = CFFI.load("lime", "lime_font_set_size", 2);
|
||||
private static var lime_font_set_size = CFFI.load("lime", "lime_font_set_size", 3);
|
||||
private static var lime_gamepad_add_mappings = CFFI.load("lime", "lime_gamepad_add_mappings", 1);
|
||||
private static var lime_gamepad_get_device_guid = CFFI.load("lime", "lime_gamepad_get_device_guid", 1);
|
||||
private static var lime_gamepad_get_device_name = CFFI.load("lime", "lime_gamepad_get_device_name", 1);
|
||||
@@ -993,7 +993,7 @@ class NativeCFFI
|
||||
return null;
|
||||
}
|
||||
|
||||
@:hlNative("lime", "hl_font_set_size") private static function lime_font_set_size(handle:CFFIPointer, size:Int):Void {}
|
||||
@:hlNative("lime", "hl_font_set_size") private static function lime_font_set_size(handle:CFFIPointer, size:Int, dpi:Int):Void {}
|
||||
|
||||
@:hlNative("lime", "hl_gamepad_add_mappings") private static function lime_gamepad_add_mappings(mappings:hl.NativeArray<String>):Void {}
|
||||
|
||||
|
||||
@@ -27,7 +27,7 @@ class LZMA
|
||||
#end
|
||||
#elseif js
|
||||
var data = untyped #if haxe4 js.Syntax.code #else __js__ #end ("LZMA.compress")(new UInt8Array(bytes.getData()), 5);
|
||||
if (data is String)
|
||||
if ((data is String))
|
||||
{
|
||||
return Bytes.ofString(data);
|
||||
}
|
||||
@@ -60,7 +60,7 @@ class LZMA
|
||||
#end
|
||||
#elseif js
|
||||
var data = untyped #if haxe4 js.Syntax.code #else __js__ #end ("LZMA.decompress")(new UInt8Array(bytes.getData()));
|
||||
if (data is String)
|
||||
if ((data is String))
|
||||
{
|
||||
return Bytes.ofString(data);
|
||||
}
|
||||
|
||||
@@ -69,7 +69,7 @@ class BackgroundWorker
|
||||
public var onProgress = new Event<Dynamic->Void>();
|
||||
|
||||
@:noCompletion private var __runMessage:Dynamic;
|
||||
#if (cpp || neko)
|
||||
#if (cpp || neko || (haxe4 && hl))
|
||||
@:noCompletion private var __messageQueue:Deque<Dynamic>;
|
||||
@:noCompletion private var __workerThread:Thread;
|
||||
#end
|
||||
@@ -87,7 +87,7 @@ class BackgroundWorker
|
||||
{
|
||||
canceled = true;
|
||||
|
||||
#if (cpp || neko)
|
||||
#if (cpp || neko || (haxe4 && hl))
|
||||
__workerThread = null;
|
||||
#end
|
||||
}
|
||||
@@ -102,7 +102,7 @@ class BackgroundWorker
|
||||
completed = false;
|
||||
__runMessage = message;
|
||||
|
||||
#if (cpp || neko)
|
||||
#if (cpp || neko || (haxe4 && hl))
|
||||
__messageQueue = new Deque<Dynamic>();
|
||||
__workerThread = Thread.create(__doWork);
|
||||
|
||||
@@ -125,7 +125,7 @@ class BackgroundWorker
|
||||
{
|
||||
completed = true;
|
||||
|
||||
#if (cpp || neko)
|
||||
#if (cpp || neko || (haxe4 && hl))
|
||||
__messageQueue.add(MESSAGE_COMPLETE);
|
||||
__messageQueue.add(message);
|
||||
#else
|
||||
@@ -143,7 +143,7 @@ class BackgroundWorker
|
||||
**/
|
||||
public function sendError(message:Dynamic = null):Void
|
||||
{
|
||||
#if (cpp || neko)
|
||||
#if (cpp || neko || (haxe4 && hl))
|
||||
__messageQueue.add(MESSAGE_ERROR);
|
||||
__messageQueue.add(message);
|
||||
#else
|
||||
@@ -161,7 +161,7 @@ class BackgroundWorker
|
||||
**/
|
||||
public function sendProgress(message:Dynamic = null):Void
|
||||
{
|
||||
#if (cpp || neko)
|
||||
#if (cpp || neko || (haxe4 && hl))
|
||||
__messageQueue.add(message);
|
||||
#else
|
||||
if (!canceled)
|
||||
@@ -193,7 +193,7 @@ class BackgroundWorker
|
||||
|
||||
@:noCompletion private function __update(deltaTime:Int):Void
|
||||
{
|
||||
#if (cpp || neko)
|
||||
#if (cpp || neko || (haxe4 && hl))
|
||||
var message = __messageQueue.pop(false);
|
||||
|
||||
if (message != null)
|
||||
|
||||
@@ -191,7 +191,18 @@ class System
|
||||
#if (!lime_doc_gen || sys)
|
||||
/**
|
||||
Attempts to exit the application. Dispatches `onExit`, and will not
|
||||
exit if the event is canceled.
|
||||
exit if the event is canceled. When exiting using this method, Lime will
|
||||
gracefully shut down a number of subsystems, including (but not limited
|
||||
to) audio, graphics, timers, and game controllers.
|
||||
|
||||
To properly exit a Lime application, it's best to call Lime's
|
||||
`System.exit()` instead of calling Haxe's built-in `Sys.exit()`. When
|
||||
targeting native platforms especially, Lime's is built on C++ libraries
|
||||
that expose functions to clean up resources properly on exit. Haxe's
|
||||
`Sys.exit()` exits immediately without giving Lime a chance to clean
|
||||
things up. With that in mind, the proper and correct way to exit a Lime
|
||||
app is by calling `lime.system.System.exit()`, and to avoid using
|
||||
`Sys.exit()`.
|
||||
**/
|
||||
public static function exit(code:Int):Void
|
||||
{
|
||||
|
||||
@@ -425,7 +425,7 @@ class ThreadPool extends WorkOutput
|
||||
{
|
||||
while (!output.__jobComplete.value && (interruption = Thread.readMessage(false)) == null)
|
||||
{
|
||||
output.workIterations.value++;
|
||||
output.workIterations.value = output.workIterations.value + 1;
|
||||
event.job.doWork.dispatch(event.job.state, output);
|
||||
}
|
||||
}
|
||||
@@ -521,7 +521,7 @@ class ThreadPool extends WorkOutput
|
||||
{
|
||||
do
|
||||
{
|
||||
workIterations.value++;
|
||||
workIterations.value = workIterations.value + 1;
|
||||
activeJob.doWork.dispatch(state, this);
|
||||
timeElapsed = timestamp() - startTime;
|
||||
}
|
||||
|
||||
@@ -34,14 +34,47 @@ import haxe.io.Path;
|
||||
@:access(lime.text.Glyph)
|
||||
class Font
|
||||
{
|
||||
/**
|
||||
* The ascender value of the font.
|
||||
*/
|
||||
public var ascender:Int;
|
||||
|
||||
/**
|
||||
* The descender value of the font.
|
||||
*/
|
||||
public var descender:Int;
|
||||
|
||||
/**
|
||||
* The height of the font.
|
||||
*/
|
||||
public var height:Int;
|
||||
|
||||
/**
|
||||
* The name of the font.
|
||||
*/
|
||||
public var name(default, null):String;
|
||||
|
||||
/**
|
||||
* The number of glyphs in the font.
|
||||
*/
|
||||
public var numGlyphs:Int;
|
||||
|
||||
|
||||
public var src:Dynamic;
|
||||
|
||||
/**
|
||||
* The underline position of the font.
|
||||
*/
|
||||
public var underlinePosition:Int;
|
||||
|
||||
/**
|
||||
* The underline thickness of the font.
|
||||
*/
|
||||
public var underlineThickness:Int;
|
||||
|
||||
/**
|
||||
* The units per EM of the font.
|
||||
*/
|
||||
public var unitsPerEM:Int;
|
||||
|
||||
@:noCompletion private var __fontID:String;
|
||||
@@ -51,6 +84,11 @@ class Font
|
||||
#end
|
||||
@:noCompletion private var __init:Bool;
|
||||
|
||||
/**
|
||||
* Creates a new instance of a Font object.
|
||||
*
|
||||
* @param name Optional name of the font.
|
||||
*/
|
||||
public function new(name:String = null)
|
||||
{
|
||||
if (name != null)
|
||||
@@ -100,6 +138,11 @@ class Font
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Decomposes the font into outline data.
|
||||
*
|
||||
* @return An instance of `NativeFontData` that contains decomposed font outline information.
|
||||
*/
|
||||
public function decompose():NativeFontData
|
||||
{
|
||||
#if (lime_cffi && !macro)
|
||||
@@ -118,6 +161,12 @@ class Font
|
||||
#end
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a Font instance from byte data.
|
||||
*
|
||||
* @param bytes The byte data containing the font.
|
||||
* @return A `Font` instance.
|
||||
*/
|
||||
public static function fromBytes(bytes:Bytes):Font
|
||||
{
|
||||
if (bytes == null) return null;
|
||||
@@ -132,6 +181,12 @@ class Font
|
||||
#end
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a Font instance from a file path.
|
||||
*
|
||||
* @param path The file path of the font.
|
||||
* @return A `Font` instance.
|
||||
*/
|
||||
public static function fromFile(path:String):Font
|
||||
{
|
||||
if (path == null) return null;
|
||||
@@ -146,11 +201,23 @@ class Font
|
||||
#end
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads a Font from byte data asynchronously.
|
||||
*
|
||||
* @param bytes The byte data containing the font.
|
||||
* @return A `Future` containing a `Font` instance.
|
||||
*/
|
||||
public static function loadFromBytes(bytes:Bytes):Future<Font>
|
||||
{
|
||||
return Future.withValue(fromBytes(bytes));
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads a Font from a file path asynchronously.
|
||||
*
|
||||
* @param path The file path of the font.
|
||||
* @return A `Future` containing a `Font` instance.
|
||||
*/
|
||||
public static function loadFromFile(path:String):Future<Font>
|
||||
{
|
||||
var request = new HTTPRequest<Font>();
|
||||
@@ -167,6 +234,12 @@ class Font
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads a Font by its name asynchronously.
|
||||
*
|
||||
* @param path The name of the font.
|
||||
* @return A `Future` containing a `Font` instance.
|
||||
*/
|
||||
public static function loadFromName(path:String):Future<Font>
|
||||
{
|
||||
#if (js && html5)
|
||||
@@ -177,6 +250,12 @@ class Font
|
||||
#end
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves a glyph from the font by a character.
|
||||
*
|
||||
* @param character The character whose glyph to retrieve.
|
||||
* @return A `Glyph` instance representing the glyph of the character.
|
||||
*/
|
||||
public function getGlyph(character:String):Glyph
|
||||
{
|
||||
#if (lime_cffi && !macro)
|
||||
@@ -186,6 +265,12 @@ class Font
|
||||
#end
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves an array of glyphs for a set of characters.
|
||||
*
|
||||
* @param characters The string containing characters to retrieve glyphs for.
|
||||
* @return An array of `Glyph` instances representing the glyphs of the characters.
|
||||
*/
|
||||
public function getGlyphs(characters:String = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^`'\"/\\&*()[]{}<>|:;_-+=?,. "):Array<Glyph>
|
||||
{
|
||||
#if (lime_cffi && !macro)
|
||||
@@ -199,6 +284,12 @@ class Font
|
||||
#end
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves metrics for a given glyph.
|
||||
*
|
||||
* @param glyph The glyph whose metrics to retrieve.
|
||||
* @return A `GlyphMetrics` instance containing the metrics of the glyph.
|
||||
*/
|
||||
public function getGlyphMetrics(glyph:Glyph):GlyphMetrics
|
||||
{
|
||||
#if (lime_cffi && !macro)
|
||||
@@ -216,34 +307,64 @@ class Font
|
||||
#end
|
||||
}
|
||||
|
||||
/**
|
||||
* Renders a specific glyph to an image.
|
||||
*
|
||||
* @param glyph The glyph to render.
|
||||
* @param fontSize The size to render the glyph at.
|
||||
* @return An `Image` instance representing the rendered glyph.
|
||||
*/
|
||||
public function renderGlyph(glyph:Glyph, fontSize:Int):Image
|
||||
{
|
||||
#if (lime_cffi && !macro)
|
||||
__setSize(fontSize);
|
||||
__setSize(fontSize, 96);
|
||||
|
||||
var bytes = Bytes.alloc(0);
|
||||
// bytes.endian = (System.endianness == BIG_ENDIAN ? "bigEndian" : "littleEndian");
|
||||
// Allocate an estimated buffer size - adjust if necessary
|
||||
var bytes:Bytes = Bytes.alloc(0); // Allocate some reasonable initial size
|
||||
|
||||
var dataPosition = 0;
|
||||
// Call native function to render glyph and get byte data
|
||||
bytes = NativeCFFI.lime_font_render_glyph(src, glyph, bytes);
|
||||
|
||||
if (bytes != null && bytes.length > 0)
|
||||
{
|
||||
var index = bytes.getInt32(dataPosition);
|
||||
dataPosition += 4;
|
||||
var width = bytes.getInt32(dataPosition);
|
||||
dataPosition += 4;
|
||||
var height = bytes.getInt32(dataPosition);
|
||||
dataPosition += 4;
|
||||
var x = bytes.getInt32(dataPosition);
|
||||
dataPosition += 4;
|
||||
var y = bytes.getInt32(dataPosition);
|
||||
var dataPosition = 0;
|
||||
|
||||
// Extract glyph information from the byte array
|
||||
var index:Int = bytes.getInt32(dataPosition);
|
||||
dataPosition += 4;
|
||||
|
||||
var data = bytes.sub(dataPosition, width * height);
|
||||
dataPosition += (width * height);
|
||||
var width:Int = bytes.getInt32(dataPosition);
|
||||
dataPosition += 4;
|
||||
|
||||
var buffer = new ImageBuffer(new UInt8Array(data), width, height, 8);
|
||||
var height:Int = bytes.getInt32(dataPosition);
|
||||
dataPosition += 4;
|
||||
|
||||
var x:Int = bytes.getInt32(dataPosition);
|
||||
dataPosition += 4;
|
||||
|
||||
var y:Int = bytes.getInt32(dataPosition);
|
||||
dataPosition += 4;
|
||||
|
||||
// Check if width and height are valid before proceeding
|
||||
if (width <= 0 || height <= 0)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
// Extract pixel data from the byte array, accounting for 32-bit RGBA data
|
||||
var pitch = width * 4; // 32-bit color data
|
||||
|
||||
// Create a new Bytes array to store the extracted bitmap data without padding
|
||||
var dataBytes = Bytes.alloc(width * height * 4);
|
||||
|
||||
// Extract row by row to handle RGBA data
|
||||
for (i in 0...height)
|
||||
{
|
||||
dataBytes.blit(i * width * 4, bytes, dataPosition + (i * pitch), width * 4);
|
||||
}
|
||||
|
||||
// Create ImageBuffer and Image from the extracted data
|
||||
var buffer = new ImageBuffer(new UInt8Array(dataBytes), width, height, 32);
|
||||
var image = new Image(buffer, 0, 0, width, height);
|
||||
image.x = x;
|
||||
image.y = y;
|
||||
@@ -254,7 +375,13 @@ class Font
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Renders a set of glyphs to images.
|
||||
*
|
||||
* @param glyphs The glyphs to render.
|
||||
* @param fontSize The size to render the glyphs at.
|
||||
* @return A `Map` containing glyphs mapped to their corresponding images.
|
||||
*/
|
||||
public function renderGlyphs(glyphs:Array<Glyph>, fontSize:Int):Map<Glyph, Image>
|
||||
{
|
||||
#if (lime_cffi && !macro)
|
||||
@@ -283,7 +410,7 @@ class Font
|
||||
var glyphList = _glyphList;
|
||||
#end
|
||||
|
||||
NativeCFFI.lime_font_set_size(src, fontSize);
|
||||
__setSize(fontSize, 96);
|
||||
|
||||
var bytes = Bytes.alloc(0);
|
||||
bytes = NativeCFFI.lime_font_render_glyphs(src, glyphList, bytes);
|
||||
@@ -587,14 +714,17 @@ class Font
|
||||
}
|
||||
#end
|
||||
|
||||
@:noCompletion private function __setSize(size:Int):Void
|
||||
@:noCompletion private function __setSize(size:Int, dpi:Int = 72):Void
|
||||
{
|
||||
#if (lime_cffi && !macro)
|
||||
NativeCFFI.lime_font_set_size(src, size);
|
||||
NativeCFFI.lime_font_set_size(src, size, dpi);
|
||||
#end
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Represents decomposed font data, containing kerning information, glyphs, and other properties.
|
||||
*/
|
||||
typedef NativeFontData =
|
||||
{
|
||||
var has_kerning:Bool;
|
||||
@@ -613,6 +743,9 @@ typedef NativeFontData =
|
||||
var kerning:Array<NativeKerningData>;
|
||||
}
|
||||
|
||||
/**
|
||||
* Represents data for an individual glyph, including dimensions and control points.
|
||||
*/
|
||||
typedef NativeGlyphData =
|
||||
{
|
||||
var char_code:Int;
|
||||
@@ -624,6 +757,9 @@ typedef NativeGlyphData =
|
||||
var points:Array<Int>;
|
||||
}
|
||||
|
||||
/**
|
||||
* Represents kerning information between two glyphs.
|
||||
*/
|
||||
typedef NativeKerningData =
|
||||
{
|
||||
var left_glyph:Int;
|
||||
|
||||
@@ -135,6 +135,12 @@ class AIRHelper
|
||||
signingOptions.push("samplePassword");
|
||||
}
|
||||
|
||||
if (project.config.exists("air.tsa"))
|
||||
{
|
||||
signingOptions.push("-tsa");
|
||||
signingOptions.push(project.config.getString("air.tsa"));
|
||||
}
|
||||
|
||||
var args = ["-package"];
|
||||
|
||||
// TODO: Is this an old workaround fixed in newer AIR SDK?
|
||||
|
||||
@@ -107,6 +107,14 @@ class HTML5Helper
|
||||
{
|
||||
suffix += "32";
|
||||
}
|
||||
else if( System.hostArchitecture == ARMV7)
|
||||
{
|
||||
suffix += "Arm";
|
||||
}
|
||||
else if( System.hostArchitecture == ARM64)
|
||||
{
|
||||
suffix += "Arm64";
|
||||
}
|
||||
else
|
||||
{
|
||||
suffix += "64";
|
||||
|
||||
@@ -99,7 +99,7 @@ class FileDialog
|
||||
if (type == null) type = FileDialogType.OPEN;
|
||||
|
||||
#if desktop
|
||||
var worker = new ThreadPool();
|
||||
var worker = new ThreadPool(#if (windows && hl) SINGLE_THREADED #end);
|
||||
|
||||
worker.onComplete.add(function(result)
|
||||
{
|
||||
@@ -224,7 +224,7 @@ class FileDialog
|
||||
public function open(filter:String = null, defaultPath:String = null, title:String = null):Bool
|
||||
{
|
||||
#if (desktop && sys)
|
||||
var worker = new ThreadPool();
|
||||
var worker = new ThreadPool(#if (windows && hl) SINGLE_THREADED #end);
|
||||
|
||||
worker.onComplete.add(function(path:String)
|
||||
{
|
||||
@@ -287,7 +287,7 @@ class FileDialog
|
||||
}
|
||||
|
||||
#if (desktop && sys)
|
||||
var worker = new ThreadPool();
|
||||
var worker = new ThreadPool(#if (windows && hl) SINGLE_THREADED #end);
|
||||
|
||||
worker.onComplete.add(function(path:String)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user