Rectangle now have a IsStoke property.

Added math functions to ExecutionEngine.
This commit is contained in:
Creeper Lv
2026-01-05 03:57:09 +11:00
parent 970b75ab92
commit 733bae29f3
10 changed files with 180 additions and 67 deletions

View File

@@ -13,6 +13,7 @@ namespace Progrart.Core.Graphics
SKPoint Start;
SKPoint Size;
SKColorF Color;
bool IsStroke;
SKShader? shader = null;
public override void SetupProperties(Engine engine)
{
@@ -26,6 +27,7 @@ namespace Progrart.Core.Graphics
__object.Set("Position", point);
}
__object.Set("StrokeWidth", 1);
__object.Set("IsStroke", true);
__object.Set("Color", ProgrartFunctions.color(engine, 1, 1, 1, 1));
{
JsObject point = new JsObject(engine);
@@ -42,6 +44,7 @@ namespace Progrart.Core.Graphics
if (__object is not null)
{
StrokeWidth = (float)__object.Get("StrokeWidth").AsNumber();
IsStroke = (bool)__object.Get("IsStroke").AsBoolean();
{
if (__object.Get("Position") is JsObject Start)
{
@@ -79,7 +82,8 @@ namespace Progrart.Core.Graphics
{
ColorF = Color,
StrokeWidth = context.TranslateSize(StrokeWidth),
Shader = shader
Shader = shader,
IsStroke = true
}
);
}

View File

@@ -1,5 +1,6 @@
using Jint;
using Jint.Native;
using System.Diagnostics;
namespace Progrart.Core.Graphics
{
@@ -24,6 +25,7 @@ namespace Progrart.Core.Graphics
float rotate;
void Transform(RenderContext context)
{
Trace.WriteLine($"Visual Root: Rotation:{rotate}");
context.canvas.Translate(tx, ty);
context.canvas.RotateDegrees(rotate, context.DrawingCore.Width / 2, context.DrawingCore.Height / 2);
if (scale != 1)
@@ -33,7 +35,7 @@ namespace Progrart.Core.Graphics
{
if (scale != 1)
context.canvas.Scale(1 / scale, 1 / scale, context.DrawingCore.Width / 2, context.DrawingCore.Height / 2);
context.canvas.RotateDegrees(rotate, context.DrawingCore.Width / 2, context.DrawingCore.Height / 2);
context.canvas.RotateDegrees(-rotate, context.DrawingCore.Width / 2, context.DrawingCore.Height / 2);
context.canvas.Translate(-tx, -ty);
}
public override void LoadProperties()
@@ -41,20 +43,20 @@ namespace Progrart.Core.Graphics
base.LoadProperties();
if (__object is null) return;
{
if (__object.Get("translate") is JsObject translate)
if (__object.Get("Translate") is JsObject translate)
{
tx = (float)translate.Get("x").AsNumber();
ty = (float)translate.Get("y").AsNumber();
}
}
{
scale = (float)__object.Get("scale").AsNumber();
scale = (float)__object.Get("Scale").AsNumber();
}
{
rotate = (float)__object.Get("rotation").AsNumber();
rotate = (float)__object.Get("Rotation").AsNumber();
}
w = (float)__object.Get("width").AsNumber();
h = (float)__object.Get("height").AsNumber();
w = (float)__object.Get("Width").AsNumber();
h = (float)__object.Get("Height").AsNumber();
}
public override void Render(RenderContext context)
{
@@ -76,16 +78,16 @@ namespace Progrart.Core.Graphics
JsObject point = new JsObject(engine);
point.Set("x", 0);
point.Set("y", 0);
__object.Set("translate", point);
__object.Set("Translate", point);
}
{
__object.Set("scale", 1);
__object.Set("Scale", 1);
}
{
__object.Set("rotation", 0);
__object.Set("Rotation", 0);
}
__object.Set("width", 1);
__object.Set("height", 1);
__object.Set("Width", 1);
__object.Set("Height", 1);
}
}
}

View File

@@ -1,4 +1,5 @@
using Jint;
using Jint.Native;
using System;
using System.Collections.Generic;
using System.Diagnostics;
@@ -6,6 +7,32 @@ using System.Text;
namespace Progrart.Core.JSExecution
{
public class MathFunctions
{
public static double abs(JsNumber v) => Math.Abs(v.AsNumber());
public static double sin(JsNumber v) => Math.Sin(v.AsNumber());
public static double cos(JsNumber v) => Math.Cos(v.AsNumber());
public static double tan(JsNumber v) => Math.Tan(v.AsNumber());
public static double tanh(JsNumber v) => Math.Tanh(v.AsNumber());
public static double asin(JsNumber v) => Math.Asin(v.AsNumber());
public static double acos(JsNumber v) => Math.Acos(v.AsNumber());
public static double atan(JsNumber v) => Math.Atan(v.AsNumber());
public static double atan2(JsNumber v, JsNumber v2) => Math.Atan2(v.AsNumber(), v2.AsNumber());
public static double atanh(JsNumber v) => Math.Atanh(v.AsNumber());
public static double sqrt(JsNumber v) => Math.Sqrt(v.AsNumber());
public static double log(JsNumber v) => Math.Log(v.AsNumber());
public static double log2(JsNumber v) => Math.Log2(v.AsNumber());
public static double log10(JsNumber v) => Math.Log10(v.AsNumber());
public static double exp(JsNumber v) => Math.Exp(v.AsNumber());
public static double ceiling(JsNumber v) => Math.Ceiling(v.AsNumber());
public static double floor(JsNumber v) => Math.Floor(v.AsNumber());
public static double log_base(JsNumber v, JsNumber v2) => Math.Log(v.AsNumber(), v2.AsNumber());
public static double pow(JsNumber v, JsNumber v2) => Math.Pow(v.AsNumber(), v2.AsNumber());
public static double round(JsNumber v) => Math.Round(v.AsNumber());
public static double sinh(JsNumber v) => Math.Sinh(v.AsNumber());
public static double cosh(JsNumber v) => Math.Cosh(v.AsNumber());
public static double cbrt(JsNumber v) => Math.Cbrt(v.AsNumber());
}
public class ExecutionEngine : IDisposable
{
public Engine Engine;
@@ -13,6 +40,28 @@ namespace Progrart.Core.JSExecution
public ExecutionEngine()
{
Engine = new Engine();
Engine.SetValue("abs", MathFunctions.abs);
Engine.SetValue("sin", MathFunctions.sin);
Engine.SetValue("cos", MathFunctions.cos);
Engine.SetValue("tan", MathFunctions.tan);
Engine.SetValue("tanh", MathFunctions.tanh);
Engine.SetValue("asin", MathFunctions.asin);
Engine.SetValue("acos", MathFunctions.acos);
Engine.SetValue("atan", MathFunctions.atan);
Engine.SetValue("atan2", MathFunctions.atan2);
Engine.SetValue("atanh", MathFunctions.atanh);
Engine.SetValue("sqrt", MathFunctions.sqrt);
Engine.SetValue("cbrt", MathFunctions.cbrt);
Engine.SetValue("pow", MathFunctions.pow);
Engine.SetValue("log", MathFunctions.log);
Engine.SetValue("log_base", MathFunctions.log_base);
Engine.SetValue("log2", MathFunctions.log2);
Engine.SetValue("log10", MathFunctions.log10);
Engine.SetValue("exp", MathFunctions.exp);
Engine.SetValue("ceiling", MathFunctions.ceiling);
Engine.SetValue("floor", MathFunctions.floor);
Engine.SetValue("sinh", MathFunctions.sinh);
Engine.SetValue("cosh", MathFunctions.cosh);
}
string formSymbol(Dictionary<string, string> symbols)
{

View File

@@ -14,13 +14,13 @@ namespace Progrart.Core.JSExecution
public ExecutionEngine engine;
public Dictionary<string, object> ObjectPool = new();
public IStorageProvider StorageProvider;
public ProgrartExecutor(IStorageProvider storageProvider)
{
engine = new ExecutionEngine();
SetupCalls();
StorageProvider = storageProvider;
}
public void SetupCalls()
public ProgrartExecutor(IStorageProvider storageProvider)
{
engine = new ExecutionEngine();
SetupCalls();
StorageProvider = storageProvider;
}
public void SetupCalls()
{
Jint.Native.Json.JsonSerializer serializer = new Jint.Native.Json.JsonSerializer(engine.Engine);
engine.Engine.SetValue("log", new Action<JsValue>((v) =>
@@ -37,6 +37,7 @@ namespace Progrart.Core.JSExecution
engine.Engine.SetValue("rectangle", rectangle);
engine.Engine.SetValue("color4", color4);
engine.Engine.SetValue("color3", color3);
engine.Engine.SetValue("color_hex", color_hex);
engine.Engine.SetValue("linear_gradient", linear_gradient);
engine.Engine.SetValue("radial_gradient", radial_gradient);
}
@@ -57,6 +58,26 @@ namespace Progrart.Core.JSExecution
, b.AsNumber()
);
}
float colorFloat(byte b) => ((float)b / (float)byte.MaxValue);
public JsObject color_hex(JsString colorString)
{
byte[] bytes = Convert.FromHexString(colorString.AsString());
if (bytes.Length == 4)
return ProgrartFunctions.color(engine.Engine
, colorFloat(bytes[0])
, colorFloat(bytes[1])
, colorFloat(bytes[2])
);
else
if (bytes.Length == 3)
return ProgrartFunctions.color(engine.Engine
, colorFloat(bytes[0])
, colorFloat(bytes[1])
, colorFloat(bytes[2])
, colorFloat(bytes[3])
);
else throw new FormatException($"{colorString.AsString()} is not a recognizable color string!");
}
public JsObject visual_root()
{
return ProgrartFunctions.CreateVisualRoot(this);
@@ -85,13 +106,12 @@ namespace Progrart.Core.JSExecution
{
height = (float)(js_height.AsNumber());
}
RenderContext renderContext = new RenderContext((int)(width * Scale), (int)(width * Scale))
RenderContext renderContext = new((int)(width * Scale), (int)(width * Scale), StorageProvider)
{
LogicalW = width,
LogicalH = height
};
ImageRoot imageRoot = new ImageRoot();
var img = engine.Engine.Call("main");
if (ObjectPool[$"{img.Get("id")}"] is BaseElement element)
imageRoot.Add(element);

View File

@@ -0,0 +1,39 @@
using Progrart.Core.Storage;
using SkiaSharp;
using System.Diagnostics;
namespace Progrart.Core
{
public class PrimitiveDrawingCore : IDisposable
{
internal bool isDisposed = false;
SKSurface surface;
SKImageInfo info;
public readonly int Width;
public readonly int Height;
public SKCanvas canvas { get; }
internal IStorageProvider StorageProvider;
public PrimitiveDrawingCore(int W, int H, IStorageProvider storageProvider)
{
Width = W;
Height = H;
Trace.WriteLine($"Createing Surface as: {W} x {H}");
info = new SKImageInfo(W, H);
surface = SKSurface.Create(info);
canvas = surface.Canvas;
canvas.Clear();
StorageProvider = storageProvider;
}
public SKData ToData()
{
return surface.Snapshot().Encode(SKEncodedImageFormat.Png, 100);
}
public void Dispose()
{
if (isDisposed) return;
//GC.SuppressFinalize(this);
isDisposed = true;
surface.Dispose();
}
}
}

View File

@@ -1,12 +1,12 @@
using SkiaSharp;
using System.Diagnostics;
using Progrart.Core.Storage;
using SkiaSharp;
namespace Progrart.Core
{
public class RenderContext
{
public PrimitiveDrawingCore DrawingCore { get; }
public IStorageProvider StorageProvider { get => DrawingCore.StorageProvider; }
public SKCanvas canvas { get => DrawingCore.canvas; }
public float LogicalW;
public float LogicalH;
@@ -26,39 +26,9 @@ namespace Progrart.Core
{
return (float)(s * Math.Sqrt(DrawingCore.Width * DrawingCore.Width + DrawingCore.Height * DrawingCore.Height) / Math.Sqrt(LogicalH * LogicalH + LogicalW * LogicalW));
}
public RenderContext(int W, int H)
public RenderContext(int W, int H, IStorageProvider StorageProvider)
{
DrawingCore = new PrimitiveDrawingCore(W, H);
}
}
public class PrimitiveDrawingCore : IDisposable
{
internal bool isDisposed = false;
SKSurface surface;
SKImageInfo info;
public readonly int Width;
public readonly int Height;
public SKCanvas canvas { get; }
public PrimitiveDrawingCore(int W, int H)
{
Width = W;
Height = H;
Trace.WriteLine($"Createing Surface as: {W} x {H}");
info = new SKImageInfo(W, H);
surface = SKSurface.Create(info);
canvas = surface.Canvas;
canvas.Clear();
}
public SKData ToData()
{
return surface.Snapshot().Encode(SKEncodedImageFormat.Png, 100);
}
public void Dispose()
{
if (isDisposed) return;
//GC.SuppressFinalize(this);
isDisposed = true;
surface.Dispose();
DrawingCore = new PrimitiveDrawingCore(W, H, StorageProvider);
}
}
[Serializable]
@@ -83,9 +53,4 @@ namespace Progrart.Core
}
}
}
[Serializable]
public class RenderConfig
{
public int Scale;
}
}