2
0
Эх сурвалжийг харах

* Swith to Float32 for coordinates and sizes

Michaël Van Canneyt 1 жил өмнө
parent
commit
0a3a96d575

+ 211 - 124
src/pas2js/fresnel.pas2js.wasmapi.pp

@@ -1,6 +1,7 @@
 {$mode objfpc}
 {$h+}
 {$modeswitch externalclass}
+{$modeswitch advancedrecords}
 
 {$DEFINE IMAGE_USEOSC}
 
@@ -42,6 +43,8 @@ Type
     Class Function AllocateCanvasID : TCanvasID;
   end;
 
+  { TCanvasEvent }
+
   TCanvasEvent = record
     CanvasID : TCanvasID;
     msg : TCanvasMessageID;
@@ -49,6 +52,8 @@ Type
     param1 : TCanvasMessageParam;
     param2 : TCanvasMessageParam;
     param3 : TCanvasMessageParam;
+    constructor Create(aCanvasID : TCanvasID; aMsg : TCanvasMessageID);
+    constructor Create(aCanvasID : TCanvasID; aMsg : TCanvasMessageID; p0 : TCanvasMessageParam; p1: TCanvasMessageParam = 0; p2: TCanvasMessageParam = 0;p3: TCanvasMessageParam = 0);
   end;
 
   { TCanvasReference }
@@ -100,13 +105,11 @@ Type
   { TWasmFresnelApi }
 
   TTimerCallback = Procedure (aCurrent,aPrevious : Double);
-  TDebugApi = (daText);
+  TDebugApi = (daText,daClipRect);
   TDebugApis = Set of TDebugApi;
 
   TWasmFresnelApi = class(TImportExtension)
   Public
-    Const
-      Int32Size = 4;
     class var
       _Keymap : TJSObject;
       _KeyCodeMap : TJSObject;
@@ -117,13 +120,15 @@ Type
     FDebugApis: TDebugApis;
     FDefaultCanvas: TCanvasReference;
     FFocusedCanvas: TCanvasReference;
+    FLastFocused: TCanvasReference;
     FLogAPICalls : Boolean;
     FTimerID : NativeInt;
     FTimerInterval: NativeInt;
     FLastTick: TDateTime;
     FKeyMap : TJSObject;
-    procedure DoGlobalClick(aEvent: TJSEvent);
-    procedure DrawBaseLine(C: TJSCanvasRenderingContext2D; S: String; X, Y: Single);
+    procedure DrawBaseLine(C: TJSCanvasRenderingContext2D; S: String; X, Y: Double);
+    procedure DrawClipRect(Ref: TCanvasReference; aX, aY, aWidth,
+      aHeight: double);
     procedure SetCreateDefaultCanvas(AValue: Boolean);
     procedure SetFocusedCanvas(AValue: TCanvasReference);
   Protected
@@ -133,48 +138,48 @@ Type
     function GetCanvas(aID : TCanvasID) : TJSCanvasRenderingContext2D;
     function GetCanvasRef(aID: TCanvasID): TCanvasReference;
     // Canvas
-    function allocatecanvas(SizeX : Longint; SizeY : Longint; aID: TWasmPointer): TCanvasError;
-    function allocateoffscreencanvas(SizeX : Longint; SizeY : Longint; aBitmap : TWasmPointer; aID: TWasmPointer): TCanvasError;
+    function allocatecanvas(SizeX, SizeY : Longint; aID: TWasmPointer): TCanvasError;
+    function allocateoffscreencanvas(SizeX, SizeY : Longint; aBitmap : TWasmPointer; aID: TWasmPointer): TCanvasError;
     function deallocatecanvas(aID: TCanvasID): TCanvasError;
     function getcanvasbyid(aCanvasElementID: TWasmPointer; aElementIDLen: Longint; aID: TWasmPointer): TCanvasError;
-    function moveto(aID : TCanvasID; X : Longint;Y : Longint): TCanvasError;
-    function lineto(aID : TCanvasID;X : Longint; Y : Longint ):  TCanvasError; 
+    function moveto(aID : TCanvasID; X, Y : TFresnelFloat): TCanvasError;
+    function lineto(aID : TCanvasID; X, Y : TFresnelFloat):  TCanvasError;
     function stroke(aID : TCanvasID): TCanvasError; 
     function beginpath(aID : TCanvasID):  TCanvasError; 
-    function arc(aID : TCanvasID;X : Longint;Y : Longint;RadiusX,RadiusY : Longint;StartAngle : Longint;EndAngle : Longint; Rotate : Longint; Flags : Longint):  TCanvasError;
-    function fillrect(aID : TCanvasID;  X : Longint; Y : Longint;  Width : Longint; Height : Longint): TCanvasError; 
-    function strokerect(aID : TCanvasID;X : Longint;Y : Longint; Width : Longint; Height : Longint ):  TCanvasError; 
-    function clearrect(aID : TCanvasID;X : Longint;Y : Longint;Width : Longint; Height : Longint ):  TCanvasError;
-    function RoundRect(aID : TCanvasID; Flags : Longint; Data : TWasmPointer) : TCanvasError;
-    function StrokeText(aID : TCanvasID;X : Longint;Y : Longint; aText : TWasmPointer; aTextLen : Longint ):  TCanvasError;
-    function FillText(aID : TCanvasID;X : Longint;Y : Longint; aText : TWasmPointer; aTextLen : Longint ):  TCanvasError;
-    function GetCanvasSizes(aID: TCanvasID; aWidth, aHeight: TWasmPointer): TCanvasError;
-    function SetCanvasSizes(aID: TCanvasID; aWidth, aHeight: Longint): TCanvasError;
+    function arc(aID : TCanvasID; X, Y, RadiusX, RadiusY, StartAngle, EndAngle, Rotate : TFresnelFloat; Flags : Longint):  TCanvasError;
+    function fillrect(aID : TCanvasID; X, Y, Width, Height : TFresnelFloat): TCanvasError;
+    function strokerect(aID : TCanvasID; X, Y, Width, Height : TFresnelFloat ):  TCanvasError;
+    function clearrect(aID : TCanvasID; X, Y, Width, Height : TFresnelFloat ):  TCanvasError;
+    function RoundRect(aID : TCanvasID; Flags : Longint; Data : PFresnelFloat) : TCanvasError;
+    function StrokeText(aID : TCanvasID; X, Y : TFresnelFloat; aText : TWasmPointer; aTextLen : Longint ):  TCanvasError;
+    function FillText(aID : TCanvasID; X,Y : TFresnelFloat; aText : TWasmPointer; aTextLen : Longint ):  TCanvasError;
+    function GetCanvasSizes(aID: TCanvasID; aWidth, aHeight: PFresnelFloat): TCanvasError;
+    function SetCanvasSizes(aID: TCanvasID; aWidth, aHeight: TFresnelFloat): TCanvasError;
     function SetFillStyle(aID: TCanvasID; aRed,aGreen,aBlue,aAlpha: TCanvasColorComponent): TCanvasError;
     function ClearCanvas(aID: TCanvasID; aRed,aGreen,aBlue,aAlpha: TCanvasColorComponent): TCanvasError;
-    function SetLinearGradientFillStyle(aID: TCanvasID; aStartX,aStartY,aEndX,aEndY : Longint; aColorPointCount : longint; aColorPoints : TWasmPointer) : TCanvasError;
-    function SetImageFillStyle(aID: TCanvasID; Flags : Longint; aImageWidth,aImageHeight: Longint; aImageData: TWasmPointer) : TCanvasError;
+    function SetLinearGradientFillStyle(aID: TCanvasID; aStartX, aStartY, aEndX, aEndY : TFresnelFloat; aColorPointCount : longint; aColorPoints : TWasmPointer) : TCanvasError;
+    function SetImageFillStyle(aID: TCanvasID; Flags : Longint; aImageWidth, aImageHeight: Longint; aImageData: TWasmPointer) : TCanvasError;
     function SetLineCap(aID: TCanvasID; aCap: TCanvasLinecap): TCanvasError;
     function SetLineJoin(aID: TCanvasID; aJoin: TCanvasLineJoin): TCanvasError;
     function SetLineMiterLimit(aID: TCanvasID; aWidth: TCanvasLineMiterLimit): TCanvasError;
-    function SetLineDash(aID: TCanvasID; aOffset : Longint; aPatternCount : longint; aPattern : TWasmPointer): TCanvasError;
+    function SetLineDash(aID: TCanvasID; aOffset : TFresnelFloat; aPatternCount : longint; aPattern : PFresnelFloat): TCanvasError;
     function SetLineWidth(aID: TCanvasID; aWidth: TCanvasLineWidth): TCanvasError;
     function SetTextBaseLine(aID: TCanvasID; aBaseLine: TCanvasTextBaseLine): TCanvasError;
     function SetStrokeStyle(aID: TCanvasID; aRed,aGreen,aBlue,aAlpha: TCanvasColorComponent): TCanvasError;
-    function DrawImage(aID : TCanvasID; aX,aY,aWidth,aHeight,aImageWidth,aImageHeight: Longint; aImageData: TWasmPointer) : TCanvasError;
-    function DrawImageEx(aID: TCanvasID; DrawData : TWasmPointer; aImageData: TWasmPointer): TCanvasError;
+    function DrawImage(aID : TCanvasID; aX, aY, aWidth, aHeight: TFresnelFloat; aImageWidth, aImageHeight: Longint; aImageData: TWasmPointer) : TCanvasError;
+    function DrawImageEx(aID: TCanvasID; DrawData : PFresnelFloat; aImageData: TWasmPointer): TCanvasError;
     function SetFont(aID : TCanvasID; aFontName : TWasmPointer; aFontNameLen : integer) : TCanvasError;
     function MeasureText(aID : TCanvasID; aText : TWasmPointer; aTextLen : integer; aMeasureData : TWasmPointer) : TCanvasError;
-    function SetTextShadowParams (aID : TCanvasID;  aOffsetX,aOffsetY,aRadius : Longint;  aRed,aGreen,aBlue,aAlpha : TCanvasColorComponent): TCanvasError;
-    function DrawPath(aID : TCanvasID; aFlags : Longint; aPathCount : longint; aPath : TWasmPointer) : TCanvasError;
-    function PointInPath(aID : TCanvasID; aX : Longint; aY : Longint; aPointCount : Integer; aPointData : TWasmPointer; aRes : TWasmPointer): TCanvasError;
-    function SetTransform(aID : TCanvasID; Flags : Longint; m11,m12,m21,m22,m31,m32 : Longint) : TCanvasError;
-    function GetViewPortSizes(Flags : Longint; aWidth, aHeight : TWasmPointer) : TCanvasError;
+    function SetTextShadowParams (aID : TCanvasID;  aOffsetX, aOffsetY, aRadius : TFresnelFloat;  aRed,aGreen,aBlue,aAlpha : TCanvasColorComponent): TCanvasError;
+    function DrawPath(aID : TCanvasID; aFlags : Longint; aPathCount : longint; aPath : PFresnelFloat) : TCanvasError;
+    function PointInPath(aID : TCanvasID; aX,aY : TFresnelFloat; aPointCount : Integer; aPointData : PFresnelFloat; aRes : TWasmPointer): TCanvasError;
+    function SetTransform(aID : TCanvasID; Flags : Longint; m11,m12,m21,m22,m31,m32 : TFresnelFloat) : TCanvasError;
+    function GetViewPortSizes(Flags : Longint; aWidth, aHeight : PFresnelFloat) : TCanvasError;
     function SetWindowTitle(aID: TCanvasID; aTitle : TWasmPointer; aTitleLen : Longint): TCanvasError;
     function SetSpecialKeyMap(Map : TWasmPointer; aLen : longint) : TCanvasError;
     function SaveState(aID : TCanvasID; aFlags : Longint) : TCanvasError;
     function RestoreState(aID : TCanvasID; aFlags : Longint) : TCanvasError;
-    function ClipAddRect(aID: TCanvasID; aX,aY: Longint; aWidth,aHeight: Longint): TCanvasError;
+    function ClipAddRect(aID: TCanvasID; aX,aY,aWidth,aHeight: TFresnelFloat): TCanvasError;
     // Timer
     function AllocateTimer(ainterval : longint; userdata: TWasmPointer) : TTimerID;
     procedure DeallocateTimer(timerid: TTimerID);
@@ -184,6 +189,11 @@ Type
     // Key handlers are global
     function DoKeyDownEvent(aEvent: TJSEvent): boolean;
     function DoKeyUpEvent(aEvent: TJSEvent): boolean;
+    // Click & enter/leave handlers to detect loss of focus.
+    procedure DoGlobalClick(aEvent: TJSEvent);
+    procedure DoGlobalEnter(aEvent: TJSEvent);
+    procedure DoGlobalLeave(aEvent: TJSEvent);
+    //
     procedure DoTimerTick; virtual;
     property DefaultCanvas : TCanvasReference Read FDefaultCanvas;
     property FocusedCanvas : TCanvasReference Read FFocusedCanvas Write SetFocusedCanvas;
@@ -247,7 +257,7 @@ class function TFresnelHelper.FresnelColorToHTMLColor(aRed,aGreen,aBlue,aAlpha:
 begin
   Result:='rgb('+inttostr(aRed shr 8)+' '+IntToStr(aGreen shr 8)+' '+inttoStr(aBlue shr 8);
   if aAlpha<>$FFFF then
-    Result:=Result+' / '+floatToStr(aAlpha/255);
+    Result:=Result+' / '+floatToStr(aAlpha/$FFFF);
   Result:=Result+')';
 end;
 
@@ -365,7 +375,7 @@ end;
 
 procedure TCanvasReference.SetFillStyle(AValue: JSValue);
 begin
-  if FFillStyle=AValue then Exit;
+//  if FFillStyle=AValue then Exit;
   FFillStyle:=AValue;
   canvascontext.fillStyle:=FFillStyle;
 end;
@@ -624,6 +634,20 @@ begin
   InstallGLobalHandlers;
 end;
 
+procedure TWasmFresnelApi.DoGlobalLeave(aEvent : TJSEvent);
+
+begin
+  FLastFocused:=FocusedCanvas;
+  FocusedCanvas:=Nil;
+end;
+
+procedure TWasmFresnelApi.DoGlobalEnter(aEvent : TJSEvent);
+
+begin
+  FocusedCanvas:=FLastFocused;
+end;
+
+
 procedure TWasmFresnelApi.DoGlobalClick(aEvent : TJSEvent);
 
 var
@@ -646,6 +670,8 @@ begin
   Document.Body.AddEventListener('keydown',@DoKeyDownEvent);
   Document.Body.AddEventListener('keyup',@DoKeyUpEvent);
   Document.Body.AddEventListener('click',@DoGlobalClick);
+  Document.Body.AddEventListener('mouseleave',@DoGlobalLeave);
+  Document.Body.AddEventListener('mouseenter',@DoGlobalEnter);
 end;
 
 function TWasmFresnelApi.ImportName: String;
@@ -673,6 +699,26 @@ begin
   Result:=_CurrentID;
 end;
 
+{ TCanvasEvent }
+
+constructor TCanvasEvent.Create(aCanvasID: TCanvasID; aMsg: TCanvasMessageID);
+begin
+  CanvasID:=aCanvasID;
+  msg:=aMsg;
+end;
+
+constructor TCanvasEvent.Create(aCanvasID: TCanvasID; aMsg: TCanvasMessageID;
+  p0: TCanvasMessageParam; p1: TCanvasMessageParam; p2: TCanvasMessageParam;
+  p3: TCanvasMessageParam);
+begin
+  CanvasID:=aCanvasID;
+  msg:=aMsg;
+  Param0:=p0;
+  Param1:=p1;
+  Param2:=p2;
+  Param3:=p3;
+end;
+
 procedure TWasmFresnelApi.LogCall(const Msg: String);
 begin
 {$IFNDEF NOLOGAPICALLS}
@@ -854,27 +900,27 @@ begin
   Result:=ECANVAS_SUCCESS;
 end;
 
-function TWasmFresnelApi.SetCanvasSizes(aID: TCanvasID; aWidth, aHeight: Longint): TCanvasError;
+function TWasmFresnelApi.SetCanvasSizes(aID: TCanvasID; aWidth, aHeight: TFresnelFloat): TCanvasError;
 
 var
   Ref: TCanvasReference;
-  w,h : Longint;
+  w,h : TFresnelFloat;
 
 begin
-  w:=Round(FresnelUnScale(aWidth));
-  h:=Round(FresnelUnScale(aHeight));
+  w:=aWidth;
+  h:=aHeight;
   {$IFNDEF NOLOGAPICALLS}
   If LogAPICalls then
     begin
-    LogCall('Canvas.SetCanvasSizes(%d,%d,%d)',[aID,w,h]);
+    LogCall('Canvas.SetCanvasSizes(%d,%g,%g)',[aID,w,h]);
     end;
   {$ENDIF}
   Ref:=GetCanvasRef(aID);
   if Not Assigned(Ref) then
     Exit(ECANVAS_NOCANVAS);
-  Ref.canvas.width:=w;
-  Ref.canvas.Height:=h;
-  Ref.canvasParent.style.setProperty('max-width',intTostr(w)+'px');
+  Ref.canvas.width:=Round(w);
+  Ref.canvas.Height:=Round(h);
+  Ref.canvasParent.style.setProperty('max-width',intTostr(Round(w))+'px');
 
   Ref.ApplyProperties;
   Result:=ECANVAS_SUCCESS;
@@ -924,7 +970,7 @@ begin
   Exit(ECANVAS_SUCCESS);
 end;
 
-function TWasmFresnelApi.SetLinearGradientFillStyle(aID: TCanvasID; aStartX, aStartY, aEndX, aEndY: Longint;
+function TWasmFresnelApi.SetLinearGradientFillStyle(aID: TCanvasID; aStartX, aStartY, aEndX, aEndY: TFresnelFloat;
   aColorPointCount: longint; aColorPoints: TWasmPointer): TCanvasError;
 
 var
@@ -946,7 +992,7 @@ begin
   {$IFNDEF NOLOGAPICALLS}
   If LogAPICalls then
     begin
-    LogCall('Canvas.SetLinearGradientFillStyle(%d,(%d,%d),(%d,%d),%d,[%x])',[aID,aStartX, aStartY, aEndX, aEndY, aColorPointCount,aColorPoints]);
+    LogCall('Canvas.SetLinearGradientFillStyle(%d,(%g,%g),(%g,%g),%d,[%x])',[aID,aStartX, aStartY, aEndX, aEndY, aColorPointCount,aColorPoints]);
     end;
   {$ENDIF}
   Canv:=GetCanvas(aID);
@@ -1030,8 +1076,7 @@ begin
   Result:=ECANVAS_SUCCESS;
 end;
 
-function TWasmFresnelApi.DrawImage(aID: TCanvasID; aX, aY, aWidth, aHeight, aImageWidth, aImageHeight: Longint;
-  aImageData: TWasmPointer): TCanvasError;
+function TWasmFresnelApi.DrawImage(aID: TCanvasID; aX, aY, aWidth, aHeight: TFresnelFloat; aImageWidth, aImageHeight: Longint; aImageData: TWasmPointer): TCanvasError;
 
 var
   V : TJSDataView;
@@ -1048,7 +1093,7 @@ begin
   {$IFNDEF NOLOGAPICALLS}
   If LogAPICalls then
     begin
-    LogCall('Canvas.DrawImage(%d,%d,%d,%d,%d,%d,%d)',[aID,aX,aY,aWidth,aHeight,aImageWidth,aImageHeight]);
+    LogCall('Canvas.DrawImage(%d,(%g,%g),(%gx%g),(%dx%d)',[aID,aX,aY,aWidth,aHeight,aImageWidth,aImageHeight]);
     end;
   {$ENDIF}
   Canv:=GetCanvas(aID);
@@ -1093,13 +1138,13 @@ var
   Function GetD(aIdx : Integer) : LongInt;
 
   begin
-    Result:=V.getInt32(DrawData+aIdx*SizeInt32,Env.IsLittleEndian);
+    Result:=Round(V.getFloat32(DrawData+aIdx*SizeFloat32,Env.IsLittleEndian));
   end;
 
   Function GetS(aIdx : Integer) : Double;
 
   begin
-    Result:=FresnelUnScale(v.getInt32(DrawData+aIdx*SizeInt32,Env.IsLittleEndian));
+    Result:=v.getFloat32(DrawData+aIdx*SizeFloat32,Env.IsLittleEndian);
   end;
 
 
@@ -1107,7 +1152,7 @@ begin
   {$IFNDEF NOLOGAPICALLS}
   If LogAPICalls then
     begin
-    LogCall('Canvas.DrawImage(%d,[%x],[%x])',[aID,DrawData,aImageData]);
+    LogCall('Canvas.DrawImageEx(%d,[%x],[%x])',[aID,DrawData,aImageData]);
     end;
   {$ENDIF}
 
@@ -1206,18 +1251,18 @@ begin
     LogCall('Canvas.MeasureText(%d,"%s") : [W: %g, H: %g, Asc: %g, Desc: %g]',[aID,S,W,H,Asc,Desc]);
     end;
   {$ENDIF}
-  D:=aMeasureData+WASMMEASURE_WIDTH*Int32Size;
-  v.setint32(D,FresnelScale(W),env.IsLittleEndian);
-  D:=aMeasureData+WASMMEASURE_HEIGHT*Int32Size;
-  v.setint32(D,FresnelScale(H),env.IsLittleEndian);
-  D:=aMeasureData+WASMMEASURE_ASCENDER*Int32Size;
-  v.setint32(D,FresnelScale(Asc),env.IsLittleEndian);
-  D:=aMeasureData+WASMMEASURE_DESCENDER*Int32Size;
-  v.setint32(D,FresnelScale(Desc),env.IsLittleEndian);
+  D:=aMeasureData+WASMMEASURE_WIDTH*SizeFloat32;
+  v.setfloat32(D,W,env.IsLittleEndian);
+  D:=aMeasureData+WASMMEASURE_HEIGHT*SizeFloat32;
+  v.setfloat32(D,H,env.IsLittleEndian);
+  D:=aMeasureData+WASMMEASURE_ASCENDER*SizeFloat32;
+  v.setfloat32(D,Asc,env.IsLittleEndian);
+  D:=aMeasureData+WASMMEASURE_DESCENDER*SizeFloat32;
+  v.setfloat32(D,Desc,env.IsLittleEndian);
   Result:=ECANVAS_SUCCESS;
 end;
 
-function TWasmFresnelApi.SetTextShadowParams (aID : TCanvasID;  aOffsetX,aOffsetY,aRadius : Longint;  aRed,aGreen,aBlue,aAlpha : TCanvasColorComponent): TCanvasError;
+function TWasmFresnelApi.SetTextShadowParams (aID : TCanvasID;  aOffsetX,aOffsetY,aRadius : TFresnelFloat;  aRed,aGreen,aBlue,aAlpha : TCanvasColorComponent): TCanvasError;
 
 var
   Canv:TJSCanvasRenderingContext2D;
@@ -1226,7 +1271,7 @@ begin
   {$IFNDEF NOLOGAPICALLS}
   If LogAPICalls then
     begin
-    LogCall('Canvas.SetTextShadowParams(%d,%d,%d,%d,"%s")',[aID,aOffsetX,aOffsetY,aRadius,TFresnelHelper.FresnelColorToHTMLColor(aRed,aGreen,aBlue,aAlpha)]);
+    LogCall('Canvas.SetTextShadowParams(%d,(%g,%g),%g,"%s")',[aID,aOffsetX,aOffsetY,aRadius,TFresnelHelper.FresnelColorToHTMLColor(aRed,aGreen,aBlue,aAlpha)]);
     end;
   {$ENDIF}
   Canv:=GetCanvas(aID);
@@ -1234,7 +1279,7 @@ begin
     Exit(ECANVAS_NOCANVAS);
   Canv.shadowOffsetX:=aOffsetX;
   Canv.shadowOffsetY:=aOffsetY;
-  Canv.shadowBlur:=FresnelUnScale(aRadius);
+  Canv.shadowBlur:=aRadius;
   Canv.shadowColor:=TFresnelHelper.FresnelColorToHTMLColor(aRed,aGreen,aBlue,aAlpha);
   Result:=ECANVAS_SUCCESS;
 end;
@@ -1318,12 +1363,13 @@ begin
   Result:=ECANVAS_SUCCESS;
 end;
 
-function TWasmFresnelApi.PointInPath(aID: TCanvasID; aX: Longint; aY: Longint;
+function TWasmFresnelApi.PointInPath(aID: TCanvasID; aX,aY: TFresnelFloat;
   aPointCount: Integer; aPointData: TWasmPointer; aRes: TWasmPointer): TCanvasError;
 var
   Canv:TJSCanvasRenderingContext2D;
   P2D : TJSPath2D;
-  aType,X,Y,X1,Y1,X2,Y2,X3,Y3,I : Integer;
+  aType, I : integer;
+  X,Y,X1,Y1,X2,Y2,X3,Y3 : TFresnelFloat;
   V : TJSDataView;
   P : TWasmPointer;
   WasClosed : Boolean;
@@ -1332,12 +1378,12 @@ var
   Procedure GetTriple;
 
   begin
-    aType:=V.getInt32(P,env.IsLittleEndian);
-    Inc(P);
-    X:=V.getInt32(P,env.IsLittleEndian);
-    inc(P);
-    Y:=V.getInt32(P,env.IsLittleEndian);
-    inc(P);
+    aType:=Round(V.getFloat32(P,env.IsLittleEndian));
+    Inc(P,SizeFloat32);
+    X:=V.getFloat32(P,env.IsLittleEndian);
+    inc(P,SizeFloat32);
+    Y:=V.getFloat32(P,env.IsLittleEndian);
+    inc(P,SizeFloat32);
   end;
 
 begin
@@ -1397,7 +1443,7 @@ begin
 end;
 
 function TWasmFresnelApi.SetTransform(aID: TCanvasID; Flags: Longint; m11, m12,
-  m21, m22, m31, m32: Longint): TCanvasError;
+  m21, m22, m31, m32: TFresnelFloat): TCanvasError;
 
 var
   Canv:TJSCanvasRenderingContext2D;
@@ -1406,20 +1452,23 @@ begin
   {$IFNDEF NOLOGAPICALLS}
   If LogAPICalls then
     begin
-    LogCall('Canvas.SetTransform(%d,%d,%d,%d,%d,%d,%d,%d)',[aID,Flags,m11,m12,m21,m22,m31,m32]);
+    LogCall('Canvas.SetTransform(%d,%d,[%g,%g,%g,%g,%g,%g])',[aID,Flags,m11,m12,m21,m22,m31,m32]);
     end;
   {$ENDIF}
   Canv:=GetCanvas(aID);
   if Not Assigned(Canv) then
     Exit(ECANVAS_NOCANVAS);
   if (Flags and TRANSFORM_RESET)<>0 then
-    canv.setTransform(FresnelUnScale(m11),FresnelUnScale(m12),FresnelUnScale(m21),FresnelUnScale(m22),FresnelUnScale(m31),FresnelUnScale(m32))
+    begin
+    canv.resetTransform();
+    canv.setTransform(m11,m12,m21,m22,m31,m32)
+    end
   else
-    canv.transform(FresnelUnScale(m11),FresnelUnScale(m12),FresnelUnScale(m21),FresnelUnScale(m22),FresnelUnScale(m31),FresnelUnScale(m32));
+    canv.transform(m11,m12,m21,m22,m31,m32);
   Result:=ECANVAS_SUCCESS;
 end;
 
-function TWasmFresnelApi.GetViewPortSizes(Flags: Longint; aWidth, aHeight: TWasmPointer): TCanvasError;
+function TWasmFresnelApi.GetViewPortSizes(Flags: Longint; aWidth, aHeight: PFresnelFloat): TCanvasError;
 
 var
   W,H : Double;
@@ -1449,8 +1498,8 @@ begin
   else
     begin
     V:=getModuleMemoryDataView;
-    v.setint32(aWidth,FresnelScale(W),env.IsLittleEndian);
-    v.setint32(aHeight,FresnelScale(H),env.IsLittleEndian);
+    v.setFloat32(aWidth,W,env.IsLittleEndian);
+    v.setFloat32(aHeight,H,env.IsLittleEndian);
     Result:=ECANVAS_SUCCESS;
     end;
 end;
@@ -1560,7 +1609,27 @@ begin
   Result:=ECANVAS_SUCCESS;
 end;
 
-function TWasmFresnelApi.ClipAddRect(aID: TCanvasID; aX,aY: Longint; aWidth,aHeight: Longint): TCanvasError;
+Procedure TWasmFresnelApi.DrawClipRect(Ref : TCanvasReference; aX,aY,aWidth,aHeight: double);
+
+var
+  col : jsvalue;
+  lw : double;
+
+begin
+  With Ref.canvascontext do
+     begin
+     col:=strokeStyle;
+     strokeStyle:='rgb(255 0 0)';
+     lw:=linewidth;
+     lineWidth:=1;
+     strokeRect(aX-1,aY-1,aWidth+2,aHeight+2);
+     //Stroke;
+     strokeStyle:=Col;
+     lineWidth:=lw;
+     end;
+end;
+
+function TWasmFresnelApi.ClipAddRect(aID: TCanvasID; aX,aY,aWidth,aHeight: TFresnelFloat): TCanvasError;
 
 var
   Ref : TCanvasReference;
@@ -1570,15 +1639,17 @@ begin
   {$IFNDEF NOLOGAPICALLS}
   If LogAPICalls then
     begin
-    LogCall('Canvas.ClipAddRect(%d,(%d,%d)-(%d,%d))',[aID,aX,aY,aWidth,aHeight]);
+    LogCall('Canvas.ClipAddRect(%d,(%g,%g)-(%gx%g))',[aID,aX,aY,aWidth,aHeight]);
     end;
   {$ENDIF}
   Result:=ECANVAS_NOCANVAS;
   Ref:=GetCanvasRef(aID);
   if Not Assigned(Ref) then
     exit;
+  if daClipRect in DebugAPIs then
+    DrawClipRect(Ref,aX,aY,aWidth,aHeight);
   P2D:=TJSPath2D.New;
-  P2D.rect(FresnelUnScale(aX),FresnelUnScale(aY),FresnelUnScale(aWidth),FresnelUnScale(aHeight));
+  P2D.rect(aX,aY,aWidth,aHeight);
   Ref.canvascontext.clip(P2D);
   Result:=ECANVAS_SUCCESS;
 end;
@@ -1630,13 +1701,13 @@ begin
   {$IFNDEF NOLOGAPICALLS}
   If LogAPICalls then
     begin
-    LogCall('Canvas.SetLineWidth(%d,%g)',[aID,FresnelUnscale(aWidth)]);
+    LogCall('Canvas.SetLineWidth(%d,%g)',[aID,aWidth]);
     end;
   {$ENDIF}
   Canv:=GetCanvas(aID);
   if Not Assigned(Canv) then
     Exit(ECANVAS_NOCANVAS);
-  Canv.LineWidth:=FresnelUnScale(aWidth);
+  Canv.LineWidth:=aWidth;
   Result:=ECANVAS_SUCCESS;
 end;
 
@@ -1718,13 +1789,13 @@ begin
   Canv:=GetCanvas(aID);
   if Not Assigned(Canv) then
     Exit(ECANVAS_NOCANVAS);
-  Canv.miterLimit:=FresnelUnscale(aWidth);
+  Canv.miterLimit:=aWidth;
   Result:=ECANVAS_SUCCESS;
   LogCall('Canvas.SetLineMiterLimit not implemented');
 end;
 
-function TWasmFresnelApi.SetLineDash(aID: TCanvasID; aOffset: Longint;
-  aPatternCount: longint; aPattern: TWasmPointer): TCanvasError;
+function TWasmFresnelApi.SetLineDash(aID: TCanvasID; aOffset: TFresnelFloat;
+  aPatternCount: longint; aPattern: PFresnelFloat): TCanvasError;
 
 var
   Dashes : TJSArray;
@@ -1737,7 +1808,7 @@ begin
   {$IFNDEF NOLOGAPICALLS}
   If LogAPICalls then
     begin
-    LogCall('Canvas.SetLineDash(%d,%g,%d,[%x])',[aID,FresnelUnscale(aOffset),aPatternCount,aPattern]);
+    LogCall('Canvas.SetLineDash(%d,%g,%d,[%x])',[aID,aOffset,aPatternCount,aPattern]);
     end;
   {$ENDIF}
   Canv:=GetCanvas(aID);
@@ -1750,11 +1821,11 @@ begin
     P:=aPattern;
     for I:=0 to APatternCount-1 do
       begin
-      Dashes.Push(FresnelUnScale(v.Getint32(P,env.IsLittleEndian)));
-      Inc(P,4);
+      Dashes.Push(v.GetFloat32(P,env.IsLittleEndian));
+      Inc(P,SizeFloat32);
       end;
     end;
-  Canv.lineDashOffset:=FresnelUnscale(aOffset);
+  Canv.lineDashOffset:=aOffset;
   Canv.setLineDash(Dashes);
 end;
 
@@ -1780,11 +1851,11 @@ begin
   v.setint32(aID,Evt.CanvasID,env.IsLittleEndian);
   v.setint32(aMsg,Evt.Msg,env.IsLittleEndian);
   v.setint32(Data,Evt.param0,env.IsLittleEndian);
-  inc(Data,Int32Size);
+  inc(Data,SizeInt32);
   v.setint32(Data,Evt.param1,env.IsLittleEndian);
-  inc(Data,Int32Size);
+  inc(Data,SizeInt32);
   v.setint32(Data,Evt.param2,env.IsLittleEndian);
-  inc(Data,Int32Size);
+  inc(Data,SizeInt32);
   v.setint32(Data,Evt.param3,env.IsLittleEndian);
   Result:=EWASMEVENT_SUCCESS;
 end;
@@ -1848,8 +1919,7 @@ begin
 end;
 
 
-function TWasmFresnelApi.allocatecanvas(SizeX: Longint; SizeY: Longint;
-  aID: TWasmPointer): TCanvasError;
+function TWasmFresnelApi.allocatecanvas(SizeX, SizeY: Longint; aID: TWasmPointer): TCanvasError;
 
 Var
   CTitle,CParent : TJSHTMLElement;
@@ -1878,8 +1948,8 @@ begin
   Canv:=TJSHTMLCanvasElement(document.createElement('CANVAS'));
   Canv.id:='ffc'+sID;
   Canv.className:='fresnel-window-client';
-  Canv.width:=SizeX;
-  Canv.height:=SizeY;
+  Canv.width:=Round(SizeX);
+  Canv.height:=Round(SizeY);
   Canv.Style.setProperty('display','block');
   CParent.AppendChild(Canv);
   V:=getModuleMemoryDataView;
@@ -1889,13 +1959,10 @@ begin
 //  Writeln('Set Ref.textBaseline ',Ref.textBaseline,' to ',Ref.canvascontext.textBaseline);
   FCanvases[sID]:=Ref;
   v.setUint32(aID, aCanvasID, env.IsLittleEndian);
-  if FFocusedCanvas=Nil then
-    FFocusedCanvas:=Ref;
   Result:=ECANVAS_SUCCESS;
 end;
 
-function TWasmFresnelApi.allocateoffscreencanvas(SizeX: Longint; SizeY: Longint; aBitmap: TWasmPointer; aID: TWasmPointer
-  ): TCanvasError;
+function TWasmFresnelApi.allocateoffscreencanvas(SizeX, SizeY: Longint; aBitmap: TWasmPointer; aID: TWasmPointer): TCanvasError;
 
 var
   aCanvasID : TCanvasID;
@@ -1925,7 +1992,7 @@ begin
   v.setUint32(aID, aCanvasID, env.IsLittleEndian);
 end;
 
-function TWasmFresnelApi.moveto(aID : TCanvasID; X : Longint;Y : Longint): TCanvasError;
+function TWasmFresnelApi.moveto(aID : TCanvasID; X, Y : TFresnelFloat): TCanvasError;
 
 Var
   C : TJSCanvasRenderingContext2D;
@@ -1933,7 +2000,7 @@ Var
 begin
   {$IFNDEF NOLOGAPICALLS}
   If LogAPICalls then
-    LogCall('Canvas.MoveTo(%d,%d,%d)',[aID,X,Y]);
+    LogCall('Canvas.MoveTo(%d,%g,%g)',[aID,X,Y]);
   {$ENDIF}
   Result:=ECANVAS_NOCANVAS;
   C:=GetCanvas(aID);
@@ -1944,7 +2011,7 @@ begin
     end;
 end;
 
-function TWasmFresnelApi.lineto(aID : TCanvasID;X : Longint; Y : Longint ):  TCanvasError; 
+function TWasmFresnelApi.lineto(aID : TCanvasID; X, Y : TFresnelFloat ):  TCanvasError;
 
 Var
   C : TJSCanvasRenderingContext2D;
@@ -1952,7 +2019,7 @@ Var
 begin
   {$IFNDEF NOLOGAPICALLS}
   If LogAPICalls then
-    LogCall('Canvas.LineTo(%d,%d,%d)',[aID,X,Y]);
+    LogCall('Canvas.LineTo(%d,%g,%g)',[aID,X,Y]);
   {$ENDIF}
   Result:=ECANVAS_NOCANVAS;
   C:=GetCanvas(aID);
@@ -2001,8 +2068,7 @@ begin
     end;
 end;
 
-function TWasmFresnelApi.arc(aID: TCanvasID; X: Longint; Y: Longint; RadiusX,
-  RadiusY: Longint; StartAngle: Longint; EndAngle: Longint; Rotate: Longint;
+function TWasmFresnelApi.arc(aID: TCanvasID; X, Y, RadiusX, RadiusY, StartAngle, EndAngle, Rotate: TFresnelFloat;
   Flags: Longint): TCanvasError;
 
 Var
@@ -2011,7 +2077,7 @@ Var
 begin
   {$IFNDEF NOLOGAPICALLS}
   If LogAPICalls then
-    LogCall('Canvas.Arc(%d,%d,%d,%d,%d,%f,%f)',[aID,X,Y,RadiusX,RadiusY,FresnelUnscale(StartAngle),FresnelUnscale(EndAngle)]);
+    LogCall('Canvas.Arc(%d,%g,%g,%g,%g,%g,%g)',[aID,X,Y,RadiusX,RadiusY,StartAngle,EndAngle]);
   {$ENDIF}
   Result:=ECANVAS_NOCANVAS;
   C:=GetCanvas(aID);
@@ -2019,9 +2085,9 @@ begin
     begin
     C.beginPath;
     if RadiusX=RadiusY then
-      C.Arc(X,y,RadiusX,FresnelUnscale(Startangle),FresnelUnscale(EndAngle))
+      C.Arc(X,y,RadiusX,Startangle,EndAngle)
     else
-      C.Ellipse(X,y,RadiusX,RadiusY,FresnelUnScale(Rotate),FresnelUnscale(Startangle),FresnelUnscale(EndAngle));
+      C.Ellipse(X,y,RadiusX,RadiusY,Rotate,Startangle,EndAngle);
     if ((Flags and ARC_FILL)<>0) then
       C.fill();
     C.stroke();
@@ -2029,7 +2095,7 @@ begin
     end;
 end;
 
-function TWasmFresnelApi.fillrect(aID : TCanvasID;  X : Longint; Y : Longint;  Width : Longint; Height : Longint): TCanvasError; 
+function TWasmFresnelApi.fillrect(aID : TCanvasID; X, Y, Width, Height : TFresnelFloat): TCanvasError;
 
 Var
   C : TJSCanvasRenderingContext2D;
@@ -2037,7 +2103,7 @@ Var
 begin
   {$IFNDEF NOLOGAPICALLS}
   If LogAPICalls then
-    LogCall('Canvas.FillRect(%d,%d,%d,%d,%d)',[aID,X,Y,Width,Height]);
+    LogCall('Canvas.FillRect(%d,%g,%g,%g,%g)',[aID,X,Y,Width,Height]);
   {$ENDIF}
   Result:=ECANVAS_NOCANVAS;
   C:=GetCanvas(aID);
@@ -2048,7 +2114,7 @@ begin
     end;
 end;
 
-function TWasmFresnelApi.strokerect(aID : TCanvasID;X : Longint;Y : Longint; Width : Longint; Height : Longint ):  TCanvasError; 
+function TWasmFresnelApi.strokerect(aID : TCanvasID; X, Y, Width, Height : TFresnelFloat):  TCanvasError;
 
 Var
   C : TJSCanvasRenderingContext2D;
@@ -2056,7 +2122,7 @@ Var
 begin
   {$IFNDEF NOLOGAPICALLS}
   If LogAPICalls then
-    LogCall('Canvas.StrokeRect(%d,%d,%d,%d,%d)',[aID,X,Y,Width,Height]);
+    LogCall('Canvas.StrokeRect(%d,%g,%g,%g,%g)',[aID,X,Y,Width,Height]);
   {$ENDIF}
   Result:=ECANVAS_NOCANVAS;
   C:=GetCanvas(aID);
@@ -2067,7 +2133,7 @@ begin
     end;
 end;
 
-function TWasmFresnelApi.clearrect(aID : TCanvasID;X : Longint;Y : Longint;Width : Longint; Height : Longint ):  TCanvasError; 
+function TWasmFresnelApi.clearrect(aID : TCanvasID; X, Y, Width, Height : TFresnelFloat):  TCanvasError;
 
 Var
   C : TJSCanvasRenderingContext2D;
@@ -2075,7 +2141,7 @@ Var
 begin
   {$IFNDEF NOLOGAPICALLS}
   If LogAPICalls then
-    LogCall('Canvas.ClearRect(%d,%d,%d,%d,%d)',[aID,X,Y,Width,Height]);
+    LogCall('Canvas.ClearRect(%d,%g,%g,%g,%g)',[aID,X,Y,Width,Height]);
   {$ENDIF}
   Result:=ECANVAS_NOCANVAS;
   C:=GetCanvas(aID);
@@ -2086,7 +2152,7 @@ begin
     end;
 end;
 
-function TWasmFresnelApi.RoundRect(aID: TCanvasID; Flags: Longint; Data: TWasmPointer): TCanvasError;
+function TWasmFresnelApi.RoundRect(aID: TCanvasID; Flags: Longint; Data: PFresnelFloat): TCanvasError;
 Var
   C : TJSCanvasRenderingContext2D;
   V : TJSDataView;
@@ -2096,7 +2162,7 @@ Var
 
   function GetElement(aOffset : Longint) : TFresnelFloat;
   begin
-    Result:=FresnelUnScale(V.getInt32(Data+(aOffset*4),Env.IsLittleEndian));
+    Result:=V.getFloat32(Data+(aOffset*SizeFloat32),Env.IsLittleEndian);
   end;
 
   Procedure AddRadius(aRX,aRY : Double);
@@ -2131,7 +2197,7 @@ begin
   Result:=ECANVAS_SUCCESS;
 end;
 
-function TWasmFresnelApi.StrokeText(aID: TCanvasID; X: Longint; Y: Longint; aText: TWasmPointer; aTextLen: Longint): TCanvasError;
+function TWasmFresnelApi.StrokeText(aID: TCanvasID; X,Y: TFresnelFloat; aText: TWasmPointer; aTextLen: Longint): TCanvasError;
 
 Var
   C : TJSCanvasRenderingContext2D;
@@ -2139,12 +2205,12 @@ Var
 
 begin
   S:=Env.GetUTF8StringFromMem(aText,aTextLen);
-  { $IFNDEF NOLOGAPICALLS}
-  // If LogAPICalls then
+  {$IFNDEF NOLOGAPICALLS}
+  If LogAPICalls then
     begin
-    LogCall('Canvas.StrokeText(%d,%d,%d,''%s'')',[aID,X,Y,S]);
+    LogCall('Canvas.StrokeText(%d,(%g,%g),''%s'')',[aID,X,Y,S]);
     end;
-  { $ENDIF}
+  {$ENDIF}
   Result:=ECANVAS_NOCANVAS;
   C:=GetCanvas(aID);
   if Assigned(C) then
@@ -2156,7 +2222,7 @@ begin
     end;
 end;
 
-procedure TWasmFresnelApi.DrawBaseLine(C: TJSCanvasRenderingContext2D; S: String; X, Y: Single);
+procedure TWasmFresnelApi.DrawBaseLine(C: TJSCanvasRenderingContext2D; S: String; X, Y: Double);
 
 var
   M : TJSTextMetrics;
@@ -2189,25 +2255,46 @@ begin
 end;
 
 procedure TWasmFresnelApi.SetFocusedCanvas(AValue: TCanvasReference);
+
+var
+  OtherID : TCanvasID;
+  Evt : TCanvasEvent;
+
 begin
   if FFocusedCanvas=AValue then Exit;
+  OtherID:=0;
+  if Assigned(FFocusedCanvas) then
+    begin
+    if assigned(aValue) then
+      OtherID:=aValue.CanvasID;
+    Evt:=TCanvasEvent.Create(FFocusedCanvas.CanvasID,WASMSG_DEACTIVATE,OtherID);
+    TJSArray(FEvents).Push(Evt);
+    ProcessMessages;
+    OtherID:=FFocusedCanvas.CanvasID;
+    end;
   FFocusedCanvas:=AValue;
+  if Assigned(FFocusedCanvas) then
+    begin
+    Evt:=TCanvasEvent.Create(FFocusedCanvas.CanvasID,WASMSG_ACTIVATE,OtherID);
+    TJSArray(FEvents).Push(Evt);
+    ProcessMessages;
+    end;
 end;
 
 
-function TWasmFresnelApi.FillText(aID: TCanvasID; X: Longint; Y: Longint; aText: TWasmPointer; aTextLen: Longint): TCanvasError;
+function TWasmFresnelApi.FillText(aID: TCanvasID; X,Y : TFresnelFloat; aText: TWasmPointer; aTextLen: Longint): TCanvasError;
 Var
   C : TJSCanvasRenderingContext2D;
   S : String;
 
 begin
   S:=Env.GetUTF8StringFromMem(aText,aTextLen);
-  { $IFNDEF NOLOGAPICALLS}
-  // If LogAPICalls then
+  {$IFNDEF NOLOGAPICALLS}
+  If LogAPICalls then
     begin
-    LogCall('Canvas.FillText(%d,%d,%d,''%s'')',[aID,X,Y,S]);
+    LogCall('Canvas.FillText(%d,(%g,%g),''%s'')',[aID,X,Y,S]);
     end;
-  { $ENDIF}
+  {$ENDIF}
   Result:=ECANVAS_NOCANVAS;
   C:=GetCanvas(aID);
   if Assigned(C) then

+ 57 - 57
src/wasm/fresnel.wasm.api.pp

@@ -58,27 +58,27 @@ function __fresnel_canvas_getbyid(
 
 function __fresnel_canvas_getsizes(
   aID : TCanvasID;
-  aWidth: PLongint;
-  aHeight: PLongint
+  aWidth: PFresnelFloat;
+  aHeight: PFresnelFloat
 ): TCanvasError; external 'fresnel_api' name 'canvas_getsizes';
 
 function __fresnel_canvas_setsizes(
   aID : TCanvasID;
-  aWidth: Longint;
-  aHeight: Longint
+  aWidth: TFresnelFloat;
+  aHeight: TFresnelFloat
 ): TCanvasError; external 'fresnel_api' name 'canvas_setsizes';
 
 
 function __fresnel_canvas_moveto(
   aID : TCanvasID;
-  X : Longint;
-  Y : Longint
+  X : TFresnelFloat;
+  Y : TFresnelFloat
 ):  TCanvasError; external 'fresnel_api' name 'canvas_moveto';
 
 function __fresnel_canvas_lineto(
   aID : TCanvasID;
-  X : Longint;
-  Y : Longint
+  X : TFresnelFloat;
+  Y : TFresnelFloat
 ):  TCanvasError; external 'fresnel_api' name 'canvas_lineto';
 
 function __fresnel_canvas_stroke(
@@ -91,31 +91,31 @@ function __fresnel_canvas_beginpath(
 
 function __fresnel_canvas_arc(
   aID : TCanvasID;
-  X : Longint;
-  Y : Longint;
-  RadiusX : Longint;
-  RadiusY : Longint;
-  StartAngle : longint;
-  EndAngle : longint;
-  Rotate : longint;
+  X : TFresnelFloat;
+  Y : TFresnelFloat;
+  RadiusX : TFresnelFloat;
+  RadiusY : TFresnelFloat;
+  StartAngle : TFresnelFloat;
+  EndAngle : TFresnelFloat;
+  Rotate : TFresnelFloat;
   Flags : Longint
 ):  TCanvasError; external 'fresnel_api' name 'canvas_arc';
 
 
 function __fresnel_canvas_fillrect(
   aID : TCanvasID;
-  X : Longint;
-  Y : Longint;
-  Width : Longint;
-  Height : Longint
+  X : TFresnelFloat;
+  Y : TFresnelFloat;
+  Width : TFresnelFloat;
+  Height : TFresnelFloat
 ):  TCanvasError; external 'fresnel_api' name 'canvas_fillrect';
 
 function __fresnel_canvas_strokerect(
   aID : TCanvasID;
-  X : Longint;
-  Y : Longint;
-  Width : Longint;
-  Height : Longint
+  X : TFresnelFloat;
+  Y : TFresnelFloat;
+  Width : TFresnelFloat;
+  Height : TFresnelFloat
 ):  TCanvasError; external 'fresnel_api' name 'canvas_strokerect';
 
 function __fresnel_canvas_roundrect(
@@ -126,24 +126,24 @@ function __fresnel_canvas_roundrect(
 
 function __fresnel_canvas_clearrect(
   aID : TCanvasID;
-  X : Longint;
-  Y : Longint;
+  X : TFresnelFloat;
+  Y : TFresnelFloat;
   Width : Longint;
   Height : Longint
 ):  TCanvasError; external 'fresnel_api' name 'canvas_clearrect';
 
 function __fresnel_canvas_stroketext(
   aID : TCanvasID;
-  X : Longint;
-  Y : Longint;
+  X : TFresnelFloat;
+  Y : TFresnelFloat;
   aText : PByte;
   aTextLen : Longint
 ):  TCanvasError; external 'fresnel_api' name 'canvas_stroketext';
 
 function __fresnel_canvas_filltext(
   aID : TCanvasID;
-  X : Longint;
-  Y : Longint;
+  X : TFresnelFloat;
+  Y : TFresnelFloat;
   aText : PByte;
   aTextLen : Longint
 ):  TCanvasError; external 'fresnel_api' name 'canvas_filltext';
@@ -200,7 +200,7 @@ function __fresnel_canvas_set_textbaseline(
 
 
 function __fresnel_canvas_set_linedash(  aID : TCanvasID;
-  aOffset : Longint;
+  aOffset : TFresnelFLoat;
   aPatternCount : longint;
   aPattern : PLineDashPatternData
 ):  TCanvasError; external 'fresnel_api' name 'canvas_set_linedash';
@@ -215,15 +215,15 @@ function __fresnel_canvas_measure_text(
   aID : TCanvasID;
   aText : PByte;
   aTextLen : Longint;
-  aWidth : PLongint;
-  aHeight : PLongint
+  aWidth : PFresnelFLoat;
+  aHeight : PFresnelFLoat
 ):  TCanvasError; deprecated 'use float versions instead';
 
 function __fresnel_canvas_measure_text(
   aID : TCanvasID;
   aText : PByte;
   aTextLen : Longint;
-  Out aWidth,aHeight,aAscender,aDescender : Single
+  Out aWidth,aHeight,aAscender,aDescender : TFresnelFloat
 ):  TCanvasError;
 
 
@@ -236,12 +236,12 @@ function __fresnel_canvas_measure_text(
 
 
 function __fresnel_canvas_set_textshadow_params (aID : TCanvasID;
-    aOffsetX,aOffsetY,aRadius : Longint;
+    aOffsetX,aOffsetY,aRadius : TFresnelFLoat;
     aRed,aGreen,aBlue,aAlpha : Longint
 ):  TCanvasError; external 'fresnel_api' name 'canvas_set_textshadow_params';
 
 function __fresnel_canvas_linear_gradient_fillstyle(aID : TCanvasID;
-    aStartX,aStartY,aEndX,aEndY : Longint;
+    aStartX,aStartY,aEndX,aEndY : TFresnelFLoat;
     aColorPointCount : longint;
     aColorPoints : PGradientColorPoints
 ):  TCanvasError; external 'fresnel_api' name 'canvas_linear_gradient_fillstyle';
@@ -254,10 +254,10 @@ function __fresnel_canvas_image_fillstyle(aID : TCanvasID;
 // Image in RGBA
 function __fresnel_canvas_draw_image(
   aID : TCanvasID;
-  aX : Longint;
-  aY : Longint;
-  aWidth : Longint;
-  aHeight : Longint;
+  aX : TFresnelFLoat;
+  aY : TFresnelFLoat;
+  aWidth : TFresnelFLoat;
+  aHeight : TFresnelFLoat;
   aImageWidth: Longint;
   aImageHeight: Longint;
   aImageData : PByte
@@ -265,16 +265,16 @@ function __fresnel_canvas_draw_image(
 
 function __fresnel_canvas_draw_image_ex(
   aID : TCanvasID;
-  aDrawData : PByte;
+  aDrawData : PFresnelFloat;
   aImageData : PByte
 ):  TCanvasError; external 'fresnel_api' name 'canvas_draw_image_ex';
 
 function __fresnel_canvas_point_in_path(
   aID : TCanvasID;
-  aX : Longint;
-  aY : Longint;
+  aX : TFresnelFLoat;
+  aY : TFresnelFLoat;
   aPointCount : Longint;
-  aPointData : PByte;
+  aPointData : PFresnelFLoat;
   aRes : PByte
 ):  TCanvasError; external 'fresnel_api' name 'canvas_point_in_path';
 
@@ -282,18 +282,18 @@ function __fresnel_canvas_draw_path(
   aID : TCanvasID;
   aFlags : Longint;
   aPointCount : Integer;
-  aPointData : PByte
+  aPointData : PFresnelFloat
 ):  TCanvasError; external 'fresnel_api' name 'canvas_draw_path';
 
 
 function __fresnel_canvas_set_transform(
  aID : TCanvasID;
  Flags : Longint;
- m11,m12,m21,m22,m31,m32 : Longint) : TCanvasError; external 'fresnel_api' name 'canvas_set_transform';
+ m11,m12,m21,m22,m31,m32 : TFresnelFLoat) : TCanvasError; external 'fresnel_api' name 'canvas_set_transform';
 
 function __fresnel_canvas_get_viewport_sizes(
  aFlags : Longint;
- aWidth,aHeight : PLongint) : TCanvasError; external 'fresnel_api' name 'canvas_get_viewport_sizes';
+ aWidth,aHeight : PFresnelFLoat) : TCanvasError; external 'fresnel_api' name 'canvas_get_viewport_sizes';
 
 function __fresnel_canvas_set_title(
   aID : TCanvasID;
@@ -313,10 +313,10 @@ function __fresnel_canvas_restore_state(
 
 function __fresnel_canvas_clip_add_rect(
   aID : TCanvasID;
-  X : Longint;
-  Y : Longint;
-  Width : Longint;
-  Height : Longint
+  X : TFresnelFloat;
+  Y : TFresnelFloat;
+  Width : TFresnelFloat;
+  Height : TFresnelFloat
 ):  TCanvasError; external 'fresnel_api' name 'canvas_clip_add_rect';
 
 
@@ -397,7 +397,7 @@ begin
   Result:=Round(len*FresnelScaleFactor);
 end;
 
-function __fresnel_canvas_measure_text(aID: TCanvasID; aText: PByte; aTextLen: Longint; aWidth: PLongint; aHeight: PLongint
+function __fresnel_canvas_measure_text(aID: TCanvasID; aText: PByte; aTextLen: Longint; aWidth: PFresnelFloat; aHeight: PFresnelFloat
   ): TCanvasError;
 
 var
@@ -408,8 +408,8 @@ begin
   Result:=__fresnel_canvas_measure_text(aID,aText,aTextLen,@Data);
   if Result=ECANVAS_SUCCESS then
     begin
-    aWidth^:=Round(FresnelUnScale(Data[WASMMEASURE_WIDTH]));
-    aHeight^:=Round(FresnelUnScale(Data[WASMMEASURE_HEIGHT]));
+    aWidth^:=Data[WASMMEASURE_WIDTH];
+    aHeight^:=Data[WASMMEASURE_HEIGHT];
     end;
 end;
 
@@ -423,10 +423,10 @@ begin
   Result:=__fresnel_canvas_measure_text(aID,aText,aTextLen,@Data);
   if Result=ECANVAS_SUCCESS then
     begin
-    aWidth:=FresnelUnScale(Data[WASMMEASURE_WIDTH]);
-    aHeight:=FresnelUnScale(Data[WASMMEASURE_HEIGHT]);
-    aAscender:=FresnelUnScale(Data[WASMMEASURE_ASCENDER]);
-    aDescender:=FresnelUnScale(Data[WASMMEASURE_DESCENDER]);
+    aWidth:=Data[WASMMEASURE_WIDTH];
+    aHeight:=Data[WASMMEASURE_HEIGHT];
+    aAscender:=Data[WASMMEASURE_ASCENDER];
+    aDescender:=Data[WASMMEASURE_DESCENDER];
     end;
 end;
 

+ 10 - 3
src/wasm/fresnel.wasm.app.pp

@@ -62,7 +62,8 @@ Type
     function GetWasmFormCount: Cardinal;
     // Event handling
     procedure HandleFresnelEnterEvent(aForm: TFresnelWasmForm; Data: PCanvasMessageData);
-    procedure HandleFresnelKeyEvent(aForm: TFresnelWasmForm; Data: PCanvasMessageData);
+    procedure HandleFresnelKeyDownEvent(aForm: TFresnelWasmForm; Data: PCanvasMessageData);
+    procedure HandleFresnelKeyUpEvent(aForm: TFresnelWasmForm; Data: PCanvasMessageData);
     procedure HandleFresnelLeaveEvent(aForm: TFresnelWasmForm; Data: PCanvasMessageData);
     procedure HandleFresnelMouseClickEvent(aForm: TFresnelWasmForm; Data: PCanvasMessageData);
     procedure HandleFresnelMouseDoubleClickEvent(aForm: TFresnelWasmForm; Data: PCanvasMessageData);
@@ -366,12 +367,17 @@ begin
 end;
 
 
-Procedure TFresnelWasmWidgetSet.HandleFresnelKeyEvent(aForm: TFresnelWasmForm; Data: PCanvasMessageData);
+Procedure TFresnelWasmWidgetSet.HandleFresnelKeyUpEvent(aForm: TFresnelWasmForm; Data: PCanvasMessageData);
 
 begin
   FLLog(etWarning,'TFresnelWasmWidgetSet.HandleFresnelKeyEvent not implemented');
 end;
 
+Procedure TFresnelWasmWidgetSet.HandleFresnelKeyDownEvent(aForm: TFresnelWasmForm; Data: PCanvasMessageData);
+
+begin
+  FLLog(etWarning,'TFresnelWasmWidgetSet.HandleFresnelKeyEvent not implemented');
+end;
 
 procedure TFresnelWasmWidgetSet.HandleFresnelEvents(aForm: TFresnelWasmForm; Msg: TCanvasMessageID; Data: PCanvasMessageData);
 
@@ -386,7 +392,8 @@ begin
     WASMSG_DBLCLICK : HandleFresnelMouseDoubleClickEvent(aForm,Data);
     WASMSG_ENTER : HandleFresnelEnterEvent(aForm,Data);
     WASMSG_LEAVE : HandleFresnelLeaveEvent(aForm,Data);
-    WASMSG_KEY : HandleFresnelKeyEvent(aForm,Data);
+    WASMSG_KEYUP : HandleFresnelKeyUpEvent(aForm,Data);
+    WASMSG_KEYDOWN : HandleFresnelKeyDownEvent(aForm,Data);
   else
     FLLog(etWarning,'Unknown message type: %d',[Msg]);
   end;

+ 22 - 30
src/wasm/fresnel.wasm.render.pp

@@ -68,14 +68,6 @@ implementation
 
 { TWasmFresnelRenderer }
 
-Function FresnelToWasmLength(aLen : TFresnelLength; Scaled : boolean = False) : Longint;
-begin
-  if Scaled then
-    Result:=Round(aLen*100)
-  else
-    Result:=Round(aLen);
-end;
-
 function TWasmFresnelRenderer.CheckFillColor(aColor : TFPColor) : Boolean;
 
 begin
@@ -111,15 +103,15 @@ procedure TWasmFresnelRenderer.SetGradientFillStyle(aGradient: TFresnelCSSLinear
 
 var
   Colors : TGradientColorPoints;
-  aX1,aY1,aX2,aY2 : Longint;
+  aX1,aY1,aX2,aY2 : TFresnelFLoat;
   P : TGradientColorPoint;
   Len,I : Integer;
 
 begin
-  aX1:=FresnelToWasmLength(aGradient.StartPoint.X);
-  aY1:=FresnelToWasmLength(aGradient.StartPoint.Y);
-  aX2:=FresnelToWasmLength(aGradient.EndPoint.X);
-  aY2:=FresnelToWasmLength(aGradient.EndPoint.Y);
+  aX1:=aGradient.StartPoint.X;
+  aY1:=aGradient.StartPoint.Y;
+  aX2:=aGradient.EndPoint.X;
+  aY2:=aGradient.EndPoint.Y;
   Len:=Length(aGradient.Colors);
   Colors:=[];
   if Len=1 then
@@ -129,7 +121,7 @@ begin
   SetLength(Colors,Len);
   For I:=0 to Length(aGradient.Colors)-1 do
     begin
-    P.Percentage:=FresnelToWasmLength(aGradient.Colors[I].Percentage,True);
+    P.Percentage:=Round(aGradient.Colors[I].Percentage*100);
     P.Red:=aGradient.Colors[I].Color.Red;
     P.Green:=aGradient.Colors[I].Color.Green;
     P.Blue:=aGradient.Colors[I].Color.Blue;
@@ -148,15 +140,15 @@ end;
 procedure TWasmFresnelRenderer.DoRoundRect(const aColor: TFPColor; const aRect: TFresnelRoundRect; Flags: Integer);
 
 var
-  RR : TCanvasRoundRectData; // Array[0..11] of longint;
+  RR : TCanvasRoundRectData; // Array[0..11] of TfresnelFLoat;
   Idx : integer;
   Corner : TFresnelCSSCorner;
 
  procedure AddP(apoint : TFresnelPoint; OffSetOrigin : Boolean = False);
  begin
-   RR[Idx]:=FresnelToWasmLength(aPoint.X+(Ord(OffSetOrigin)*Origin.X),True);
+   RR[Idx]:=aPoint.X+(Ord(OffSetOrigin)*Origin.X);
    Inc(Idx);
-   RR[Idx]:=FresnelToWasmLength(aPoint.Y+(Ord(OffSetOrigin)*Origin.Y),True);
+   RR[Idx]:=aPoint.Y+(Ord(OffSetOrigin)*Origin.Y);
    Inc(Idx);
  end;
 
@@ -208,8 +200,8 @@ procedure TWasmFresnelRenderer.DoFillRect(const aColor: TFPColor; const aRect: T
 begin
   if CheckFill then
     CheckFillColor(aColor);
-  FLLog(etDebug,'__fresnel_canvas_fillrect(%d,%d,%d,%d,%d)',[Canvas,FresnelToWasmLength(aRect.Left+Origin.X),FresnelToWasmLength(aRect.Top+Origin.Y),FresnelToWasmLength(aRect.Width),FresnelToWasmLength(aRect.Height)]);
-  __fresnel_canvas_fillrect(Canvas,FresnelToWasmLength(aRect.Left+Origin.X),FresnelToWasmLength(aRect.Top+Origin.Y),FresnelToWasmLength(aRect.Width),FresnelToWasmLength(aRect.Height));
+  FLLog(etDebug,'__fresnel_canvas_fillrect(%d,%d,%d,%d,%d)',[Canvas,aRect.Left+Origin.X,aRect.Top+Origin.Y,aRect.Width,aRect.Height]);
+  __fresnel_canvas_fillrect(Canvas,(aRect.Left+Origin.X),(aRect.Top+Origin.Y),(aRect.Width),(aRect.Height));
 end;
 
 procedure TWasmFresnelRenderer.FillRect(const aColor: TFPColor; const aRect: TFresnelRect);
@@ -223,8 +215,8 @@ begin
   CheckStrokeColor(aColor);
   __fresnel_canvas_set_linewidth(Canvas,200);
   __fresnel_canvas_beginpath(Canvas);
-  __fresnel_canvas_moveto(Canvas,FresnelToWasmLength(x1+Origin.X),FresnelToWasmLength(y1+Origin.y));
-  __fresnel_canvas_lineto(Canvas,FresnelToWasmLength(x2+Origin.X),FresnelToWasmLength(y2+Origin.Y));
+  __fresnel_canvas_moveto(Canvas, (x1+Origin.X), (y1+Origin.Y));
+  __fresnel_canvas_lineto(Canvas, (x2+Origin.X), (y2+Origin.Y));
   __fresnel_canvas_stroke(Canvas);
 end;
 
@@ -244,7 +236,7 @@ begin
     // X,Y,Radius,r,g,b,a)
     if __fresnel_canvas_set_textshadow_params(Canvas,0,0,0,0,0,0,0)<>ECANVAS_SUCCESS then
       FLLog(etError,'failed to clear shadow params for text "%s"',[Canvas,aText]);
-    if __fresnel_canvas_filltext(Canvas,FresnelToWasmLength(aLeft+Origin.X),FresnelToWasmLength(aTop+Origin.Y),PByte(aText),Length(aText))<>ECANVAS_SUCCESS then
+    if __fresnel_canvas_filltext(Canvas,(aLeft+Origin.X),(aTop+Origin.Y),PByte(aText),Length(aText))<>ECANVAS_SUCCESS then
       FLLog(etError,'failed to draw canvas %d text "%s"',[Canvas,aText]);
     end
   else
@@ -252,9 +244,9 @@ begin
       begin
       aShadow:=Self.TextShadow[I];
       With aShadow^ do
-        if __fresnel_canvas_set_textshadow_params(Canvas,FresnelToWasmLength(Offset.X),FresnelToWasmLength(Offset.Y),FresnelToWasmLength(Radius,True),Color.Red,Color.Green,Color.Blue,Color.Alpha)<>ECANVAS_SUCCESS then
+        if __fresnel_canvas_set_textshadow_params(Canvas,(Offset.X),(Offset.Y),Radius,Color.Red,Color.Green,Color.Blue,Color.Alpha)<>ECANVAS_SUCCESS then
           FLLog(etError,'failed to set shadow params for text "%s"',[Canvas,aText]);
-      if __fresnel_canvas_filltext(Canvas,FresnelToWasmLength(aLeft+Origin.X),FresnelToWasmLength(aTop+Origin.Y),PByte(aText),Length(aText))<>ECANVAS_SUCCESS then
+      if __fresnel_canvas_filltext(Canvas,(aLeft+Origin.X),(aTop+Origin.Y),PByte(aText),Length(aText))<>ECANVAS_SUCCESS then
         FLLog(etError,'failed to draw canvas %d text "%s"',[Canvas,aText]);
       if __fresnel_canvas_set_textshadow_params(Canvas,0,0,0,0,0,0,0)<>ECANVAS_SUCCESS then
         FLLog(etError,'failed to clear shadow params for text "%s"',[Canvas,aText]);
@@ -275,10 +267,10 @@ begin
     if Img<>aImage then
       Img.Assign(aImage);
     __fresnel_canvas_draw_image(Canvas,
-                                FresnelToWasmLength(aLeft+Origin.X),
-                                FresnelToWasmLength(aTop+Origin.Y),
-                                FresnelToWasmLength(aWidth),
-                                FresnelToWasmLength(aHeight),
+                                aLeft+Origin.X,
+                                aTop+Origin.Y,
+                                aWidth,
+                                aHeight,
                                 Img.Width,
                                 Img.Height,
                                 Img.RawData);
@@ -302,7 +294,7 @@ begin
   end else if Params.BackgroundColorFP.Alpha>alphaTransparent then
   begin
     //FLLog(etDebug,'TFresnelRenderer.DrawElBorder drawing background %s',[El.GetPath]);
-    __fresnel_canvas_set_linewidth(Canvas,FresnelToWasmLength(Params.Width[ffsLeft],True));
+    __fresnel_canvas_set_linewidth(Canvas,Params.Width[ffsLeft]);
     if Params.HasRadius then
       RoundRect(Params.BackgroundColorFP,Params.BoundingBox,True)
     else
@@ -324,7 +316,7 @@ begin
     Inherited DrawElBorder(El,Params)
   else if Params.SameBorderWidth then
     begin
-    __fresnel_canvas_set_linewidth(Canvas,FresnelToWasmLength(Params.Width[ffsLeft],True));
+    __fresnel_canvas_set_linewidth(Canvas,Params.Width[ffsLeft]);
     BB:=Params.BoundingBox;
     With Params do
       begin

+ 25 - 16
src/wasm/fresnel.wasm.shared.pp

@@ -39,25 +39,26 @@ Type
   {$ELSE}
   TFresnelFloat = double;
   {$ENDIF}
+  TFresnelFloatArray = Array of TFresnelFloat;
 
   TCanvasError = longint;
   TCanvasID = longint;
   TCanvasColorComponent = Word; // one of R G B A
   TCanvasColor = longint;
-  TCanvasLineWidth = longint; // Width * 100
+  TCanvasLineWidth = TFresnelFloat;
   TCanvasLineCap = byte;
   TCanvasLineJoin = byte;
   TCanvasTextBaseLine = Byte;
-  TCanvasLineMiterLimit = longint;
+  TCanvasLineMiterLimit = TFresnelFloat;
 
   TCanvasMessageID = longint;
   TCanvasMessageParam = longint;
   TCanvasMessageData = Array[0..CanvasMsgSize-1] of TCanvasMessageParam;
 
-  TCanvasMeasureTextParam = longint;
+  TCanvasMeasureTextParam = TFresnelFloat;
   TCanvasMeasureTextData = Array[0..CanvasMeasureTextSize] of TCanvasMeasureTextParam;
 
-  TLineDashPattern = longint; // Scaled 100
+  TLineDashPattern = TFresnelFloat;
   TLineDashPatternData = Array of TLineDashPattern;
 
   {$IFDEF PAS2JS}
@@ -65,7 +66,7 @@ Type
   {$ENDIF}
 
   TTimerID = longint;
-  TCanvasRoundRectData = Array[0..11] of longint;
+  TCanvasRoundRectData = Array[0..11] of TFresnelFloat;
 
   { TGradientColorPoint }
 
@@ -83,6 +84,7 @@ Type
   end;
 
   {$IFNDEF PAS2JS}
+  PFresnelFloat = ^TFresnelFloat;
   PCanvasID = ^TCanvasID;
   PCanvasColor = ^TCanvasColor;
   PCanvasMessageID = ^TCanvasMessageID;
@@ -92,16 +94,19 @@ Type
   PGradientColorPoints = ^TGradientColorPoint;
   PLineDashPatternData = ^TLineDashPattern;
   PKeyMap = PLongint;
+  TWasmPointer = Pointer;
   {$ELSE}
-  PCanvasID = Longint;
-  PCanvasColor = Longint;
-  PCanvasMessageID = Longint;
-  PCanvasMessageData = Longint;
-  PCanvasMeasureTextData = Longint;
-  PCanvasRoundRectData = Longint;
-  PGradientColorPoints = Longint;
-  PLineDashPatternData = Longint;
-  PKeyMap = Longint;
+  TWasmPointer = Longint;
+  PFresnelFloat = TWasmPointer;
+  PCanvasID = TWasmPointer;
+  PCanvasColor = TWasmPointer;
+  PCanvasMessageID = TWasmPointer;
+  PCanvasMessageData = TWasmPointer;
+  PCanvasMeasureTextData = TWasmPointer;
+  PCanvasRoundRectData = TWasmPointer;
+  PGradientColorPoints = TWasmPointer;
+  PLineDashPatternData = TWasmPointer;
+  PKeyMap = TWasmPointer;
   {$ENDIF}
 
 Const
@@ -170,6 +175,8 @@ Const
   WASMSG_LEAVE       = 9;
   WASMSG_KEYDOWN     = 10;
   WASMSG_KEYUP       = 11;
+  WASMSG_ACTIVATE    = 12;
+  WASMSG_DEACTIVATE  = 13;
 
   // Roundrect flags
   ROUNDRECT_FLAG_FILL         = 1;
@@ -243,12 +250,14 @@ Function LineCapToString(aCap: TCanvasLineCap) : String;
 Function LineJoinToString(aJoin: TCanvasLineJoin) : String;
 Function TextBaseLineToString(aBaseLine : TCanvasTextBaseLine) : String;
 
+{
 Function FresnelUnScale(aLen : Longint) : TFresnelFloat;
 Function FresnelScale(aLen : TFresnelFloat) : Longint;
-
+}
 
 implementation
 
+{
 Function FresnelUnScale(aLen : Longint) : TFresnelFloat;
 
 begin
@@ -260,7 +269,7 @@ Function FresnelScale(aLen : TFresnelFloat) : Longint;
 begin
   Result:=Round(aLen*FresnelScaleFactor);
 end;
-
+}
 
 function LineCapToString(aCap: TCanvasLineCap): String;