浏览代码

* Additional calls: ClearCanvas, DrawPath, PointInPath, setTransform

Michaël Van Canneyt 1 年之前
父节点
当前提交
6afdbc83bb
共有 3 个文件被更改,包括 297 次插入21 次删除
  1. 226 17
      src/pas2js/fresnel.pas2js.wasmapi.pp
  2. 38 0
      src/wasm/fresnel.wasm.api.pp
  3. 33 4
      src/wasm/fresnel.wasm.shared.pp

+ 226 - 17
src/pas2js/fresnel.pas2js.wasmapi.pp

@@ -104,6 +104,7 @@ Type
     function FillText(aID : TCanvasID;X : Longint;Y : Longint; aText : TWasmPointer; aTextLen : Longint ):  TCanvasError;
     function GetCanvasSizes(aID: TCanvasID; aWidth, aHeight: TWasmPointer): 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 SetLineCap(aID: TCanvasID; aCap: TCanvasLinecap): TCanvasError;
@@ -116,13 +117,12 @@ Type
     function SetFont(aID : TCanvasID; aFontName : TWasmPointer; aFontNameLen : integer) : TCanvasError;
     function MeasureText(aID : TCanvasID; aText : TWasmPointer; aTextLen : integer; aWidth,aHeight : Longint) : 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;
     // Timer
     function AllocateTimer(ainterval : longint; userdata: TWasmPointer) : TTimerID;
     procedure DeallocateTimer(timerid: TTimerID);
-{    function __fresnel_timer_allocate(ainterval : longint; userdata: pointer) : TTimerID; external 'fresnel_api' name 'timer_allocate';
-    procedure __fresnel_timer_deallocate(timerid: TTimerID); external 'fresnel_api' name 'timer_deallocate';
-}
     // Events
     function GetEvent(aID: TWasmPointer; aMsg: TWasmPointer; Data : TWasmPointer): TCanvasError;
     function GetEventCount(aCount: TWasmPointer): TCanvasError;
@@ -488,7 +488,10 @@ begin
   aObject['canvas_measure_text']:=@MeasureText;
   aObject['canvas_set_textshadow_params']:=@SetTextShadowParams;
   aObject['canvas_roundrect']:=@RoundRect;
-
+  aObject['canvas_draw_path']:=@DrawPath;
+  aObject['canvas_point_in_path']:=@PointInPath;
+  aObject['canvas_set_transform']:=@SetTransForm;
+  aObject['canvas_clear']:=@ClearCanvas;
   // Timer
   aObject['timer_allocate']:=@AllocateTimer;
   aObject['timer_deallocate']:=@DeAllocateTimer;
@@ -509,14 +512,24 @@ end;
 
 function TWasmFresnelApi.GetCanvasSizes(aID: TCanvasID; aWidth, aHeight: TWasmPointer): TCanvasError;
 
+var
+  Ref: TCanvasReference;
+  v : TJSDataView;
+
 begin
   {$IFNDEF NOLOGAPICALLS}
   If LogAPICalls then
     begin
-    LogCall('Canvas.FillText(%d,%d,%d)',[aID,aWidth,aHeight]);
+    LogCall('Canvas.GetCanvasSizes(%d,[%x],[%x])',[aID,aWidth,aHeight]);
     end;
   {$ENDIF}
-  LogCall('Canvas.GetCanvasSizes not implemented');
+  Ref:=GetCanvasRef(aID);
+  if Not Assigned(Ref) then
+    Exit(ECANVAS_NOCANVAS);
+  v:=getModuleMemoryDataView;
+  v.setint32(aWidth,Ref.canvas.width,env.IsLittleEndian);
+  v.setint32(aHeight,Ref.canvas.height,env.IsLittleEndian);
+  Result:=ECANVAS_SUCCESS;
 end;
 
 function TWasmFresnelApi.SetFillStyle(aID: TCanvasID; aRed, aGreen, aBlue, aAlpha: TCanvasColorComponent): TCanvasError;
@@ -541,6 +554,30 @@ begin
   Exit(ECANVAS_SUCCESS);
 end;
 
+function TWasmFresnelApi.ClearCanvas(aID: TCanvasID; aRed, aGreen, aBlue,
+  aAlpha: TCanvasColorComponent): TCanvasError;
+
+var
+  Ref : TCanvasReference;
+  S : String;
+
+begin
+  {$IFNDEF NOLOGAPICALLS}
+  If LogAPICalls then
+    begin
+    LogCall('Canvas.SetFillStyle(%d,%d,%d,%d,%d)',[aID,aRed,aGreen,aBlue,aAlpha]);
+    end;
+  {$ENDIF}
+  Ref:=GetCanvasRef(aID);
+  if Not Assigned(ref) then
+    Exit(ECANVAS_NOCANVAS);
+  S:=TFresnelHelper.FresnelColorToHTMLColor(aRed,aGreen,aBlue,aAlpha);
+  //  Writeln('Fill: ',S);
+  Ref.canvascontext.fillStyle:=S;
+  Ref.canvascontext.FillRect(0,0,Ref.canvas.width,Ref.canvas.height);
+  Exit(ECANVAS_SUCCESS);
+end;
+
 function TWasmFresnelApi.SetLinearGradientFillStyle(aID: TCanvasID; aStartX, aStartY, aEndX, aEndY: Longint;
   aColorPointCount: longint; aColorPoints: TWasmPointer): TCanvasError;
 
@@ -710,15 +747,6 @@ begin
     Exit(ECANVAS_NOCANVAS);
   Canv.font:=S;
   Result:=ECANVAS_SUCCESS;
-(*
-function __fresnel_canvas_measure_text(
-        aID : TCanvasID;
-        aText : PByte;
-        aTextLen : Longint;
-        aWidth : PLongint;
-        aHeight : PLongint
-      ):  TCanvasError; external 'fresnel_api' name 'canvas_measure_text';
-*)
 end;
 
 function TWasmFresnelApi.MeasureText(aID: TCanvasID; aText: TWasmPointer; aTextLen: integer; aWidth, aHeight: Longint
@@ -780,6 +808,185 @@ begin
   Result:=ECANVAS_SUCCESS;
 end;
 
+function TWasmFresnelApi.DrawPath(aID: TCanvasID; aFlags: Longint;
+  aPathCount: longint; aPath: TWasmPointer): TCanvasError;
+var
+  Canv:TJSCanvasRenderingContext2D;
+  P2D : TJSPath2D;
+  aType,X,Y,X1,Y1,X2,Y2,X3,Y3,I : Integer;
+  V : TJSDataView;
+  P : TWasmPointer;
+  WasClosed : Boolean;
+
+  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);
+  end;
+
+begin
+  {$IFNDEF NOLOGAPICALLS}
+  If LogAPICalls then
+    begin
+    LogCall('Canvas.DrawPath(%d,%d,%d,[%x])',[aID,aFlags,aPathCount,aPath]);
+    end;
+  {$ENDIF}
+  WasClosed:=False;
+  Canv:=GetCanvas(aID);
+  if Not Assigned(Canv) then
+    Exit(ECANVAS_NOCANVAS);
+  if aPathCount=0 then
+    Exit(ECANVAS_INVALIDPATH);
+  V:=getModuleMemoryDataView;
+  P:=aPath;
+  P2D:=TJSPath2D.New;
+  For I:=1 to aPathCount-1 do
+    begin
+    GetTriple;
+    WasClosed:=aType<>DRAWPATH_TYPECLOSE;
+    Case aType of
+      DRAWPATH_TYPEMOVETO : P2D.MoveTo(X,Y);
+      DRAWPATH_TYPELINETO : P2D.LineTo(X,Y);
+      DRAWPATH_TYPECURVETO :
+        begin
+        X1:=X;
+        Y1:=Y;
+        GetTriple;
+        if aType<>DRAWPATH_TYPECURVETO then
+          begin
+          Writeln('Invalid path data 2, expected CURVETO (',DRAWPATH_TYPECURVETO,'), got: ',aType);
+          exit;
+          end;
+        X2:=X;
+        Y2:=Y;
+        GetTriple;
+        if aType<>DRAWPATH_TYPECURVETO then
+          begin
+          Writeln('Invalid path data 3, expected CURVETO (',DRAWPATH_TYPECURVETO,'), got: ',aType);
+          exit;
+          end;
+        X3:=X;
+        Y3:=Y;
+        P2D.bezierCurveTo(X1,Y1,X2,Y2,X3,Y3);
+        end;
+      DRAWPATH_TYPECLOSE :
+        P2D.ClosePath;
+      end;
+    end;
+  if not WasClosed and ((aFlags and DRAWPATH_CLOSEPATH)<>0) then
+    P2D.closePath;
+  if (aFlags and DRAWPATH_FILLPATH)<>0 then
+    Canv.Fill(P2D);
+  if (aFlags and DRAWPATH_STROKEPATH)<>0 then
+    Canv.Stroke(P2D);
+  Result:=ECANVAS_SUCCESS;
+end;
+
+function TWasmFresnelApi.PointInPath(aID: TCanvasID; aX: Longint; aY: Longint;
+  aPointCount: Integer; aPointData: TWasmPointer; aRes: TWasmPointer): TCanvasError;
+var
+  Canv:TJSCanvasRenderingContext2D;
+  P2D : TJSPath2D;
+  aType,X,Y,X1,Y1,X2,Y2,X3,Y3,I : Integer;
+  V : TJSDataView;
+  P : TWasmPointer;
+  WasClosed : Boolean;
+  Res : Boolean;
+
+  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);
+  end;
+
+begin
+  {$IFNDEF NOLOGAPICALLS}
+  If LogAPICalls then
+    begin
+    LogCall('Canvas.PointInPath(%d,(%d,%d),%d,[%x],[%x])',[aID,aX,aY,aPointCount,aPointData,aRes]);
+    end;
+  {$ENDIF}
+  WasClosed:=False;
+  Canv:=GetCanvas(aID);
+  if Not Assigned(Canv) then
+    Exit(ECANVAS_NOCANVAS);
+  if aPointCount=0 then
+    Exit(ECANVAS_INVALIDPATH);
+  V:=getModuleMemoryDataView;
+  P:=aPointData;
+  P2D:=TJSPath2D.New;
+  For I:=1 to aPointCount-1 do
+    begin
+    GetTriple;
+    WasClosed:=aType<>DRAWPATH_TYPECLOSE;
+    Case aType of
+      DRAWPATH_TYPEMOVETO : P2D.MoveTo(X,Y);
+      DRAWPATH_TYPELINETO : P2D.LineTo(X,Y);
+      DRAWPATH_TYPECURVETO :
+        begin
+        X1:=X;
+        Y1:=Y;
+        GetTriple;
+        if aType<>DRAWPATH_TYPECURVETO then
+          begin
+          Writeln('Invalid path data 2, expected CURVETO (',DRAWPATH_TYPECURVETO,'), got: ',aType);
+          exit(ECANVAS_INVALIDPATH);
+          end;
+        X2:=X;
+        Y2:=Y;
+        GetTriple;
+        if aType<>DRAWPATH_TYPECURVETO then
+          begin
+          Writeln('Invalid path data 3, expected CURVETO (',DRAWPATH_TYPECURVETO,'), got: ',aType);
+          exit(ECANVAS_INVALIDPATH);
+          end;
+        X3:=X;
+        Y3:=Y;
+        P2D.bezierCurveTo(X1,Y1,X2,Y2,X3,Y3);
+        end;
+      DRAWPATH_TYPECLOSE :
+        P2D.ClosePath;
+      end;
+    end;
+  if not WasClosed then
+    P2D.closePath;
+  Res:=Canv.isPointInPath(P2D,aX,aY);
+  v.setInt8(aRes,Ord(Res));
+  Result:=ECANVAS_SUCCESS;
+end;
+
+function TWasmFresnelApi.SetTransform(aID: TCanvasID; Flags: Longint; m11, m12,
+  m21, m22, m31, m32: Longint): TCanvasError;
+
+var
+  Canv:TJSCanvasRenderingContext2D;
+
+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]);
+    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))
+  else
+    canv.transform(FresnelUnScale(m11),FresnelUnScale(m12),FresnelUnScale(m21),FresnelUnScale(m22),FresnelUnScale(m31),FresnelUnScale(m32));
+end;
+
 function TWasmFresnelApi.AllocateTimer(ainterval: longint; userdata: TWasmPointer): TTimerID;
 
 var
@@ -1138,7 +1345,9 @@ begin
     end;
 end;
 
-function TWasmFresnelApi.Arc(aID : TCanvasID;X : Longint;Y : Longint;RadiusX,RadiusY : Longint;StartAngle : Longint;EndAngle : Longint; Rotate : Longint; Flags : Longint):  TCanvasError;
+function TWasmFresnelApi.arc(aID: TCanvasID; X: Longint; Y: Longint; RadiusX,
+  RadiusY: Longint; StartAngle: Longint; EndAngle: Longint; Rotate: Longint;
+  Flags: Longint): TCanvasError;
 
 Var
   C : TJSCanvasRenderingContext2D;

+ 38 - 0
src/wasm/fresnel.wasm.api.pp

@@ -138,6 +138,15 @@ function __fresnel_canvas_set_fillstyle(
   aAlpha : Longint
 ):  TCanvasError; external 'fresnel_api' name 'canvas_set_fillstyle';
 
+function __fresnel_canvas_clear(
+  aID : TCanvasID;
+  aRed : Longint;
+  aGreen: Longint;
+  aBlue : Longint;
+  aAlpha : Longint
+):  TCanvasError; external 'fresnel_api' name 'canvas_clear';
+
+
 function __fresnel_canvas_set_strokestyle(
   aID : TCanvasID;
   aRed : Longint;
@@ -215,6 +224,35 @@ function __fresnel_canvas_draw_image(
   aImageData : PByte
 ):  TCanvasError; external 'fresnel_api' name 'canvas_draw_image';
 
+function __fresnel_canvas_draw_image_ex(
+  aID : TCanvasID;
+  aDrawData : PByte;
+  aImageData : PByte
+):  TCanvasError; external 'fresnel_api' name 'canvas_draw_image_ex';
+
+function __fresnel_canvas_point_in_path(
+  aID : TCanvasID;
+  aX : Longint;
+  aY : Longint;
+  aPointCount : Integer;
+  aPointData : PByte;
+  aRes : PByte
+):  TCanvasError; external 'fresnel_api' name 'canvas_point_in_path';
+
+function __fresnel_canvas_draw_path(
+  aID : TCanvasID;
+  aFlags : Longint;
+  aPointCount : Integer;
+  aPointData : PByte
+):  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';
+
+
 { ---------------------------------------------------------------------
   Timer API
   ---------------------------------------------------------------------}

+ 33 - 4
src/wasm/fresnel.wasm.shared.pp

@@ -89,6 +89,7 @@ Type
 Const
   ECANVAS_SUCCESS     = 0;
   ECANVAS_NOCANVAS    = 1;
+  ECANVAS_INVALIDPATH = 2;
   ECANVAS_UNSPECIFIED = -1;
 
   CANVAS_LINECAP_BUTT   = 0;
@@ -116,10 +117,12 @@ Const
   WASM_KEYSTATE_HYPER   = 1 shl Ord(ssHyper);
   WASM_KEYSTATE_ALTGR   = 1 shl Ord(ssAltGr);
 
-  WASMSG_MOUSESTATE_X      = 0;
-  WASMSG_MOUSESTATE_Y      = 1;
-  WASMSG_MOUSESTATE_STATE  = 2;
-  WASMSG_MOUSESTATE_BUTTON = 3;
+  // Location of data in parameters array
+  WASMSG_MOUSESTATE_X        = 0;
+  WASMSG_MOUSESTATE_Y        = 1;
+  WASMSG_MOUSESTATE_STATE    = 2;
+  WASMSG_MOUSESTATE_BUTTON   = 3;
+  WASMSG_MOUSESTATE_DISTANCE = 3;
 
 Const
   WASMSG_NONE        = 0;
@@ -158,10 +161,36 @@ Const
   IMAGEFILLSTYLE_REPEATX   = 2;
   IMAGEFILLSTYLE_REPEATY   = 3;
 
+  DRAWIMAGE_DESTX       = 0;
+  DRAWIMAGE_DESTY       = 1;
+  DRAWIMAGE_DESTWIDTH   = 2;
+  DRAWIMAGE_DESTHEIGHT  = 3;
+  DRAWIMAGE_SRCX        = 4;
+  DRAWIMAGE_SRCY        = 5;
+  DRAWIMAGE_SRCWIDTH    = 6;
+  DRAWIMAGE_SRCHEIGHT   = 7;
+  DRAWIMAGE_IMAGEWIDTH  = 8;
+  DRAWIMAGE_IMAGEHEIGHT = 9;
+
+  // Set_transform_flags
+  TRANSFORM_RESET = 1;
+
   // Flags for Arc
   ARC_FILL   = 1;
   ARC_ROTATE = 2;
 
+  // Flags for DrawPath
+  DRAWPATH_CLOSEPATH  = 1;
+  DRAWPATH_FILLPATH   = 2;
+  DRAWPATH_STROKEPATH = 4;
+
+  // Point types in DrawPath
+  DRAWPATH_TYPEMOVETO  = 0;
+  DRAWPATH_TYPELINETO  = 1;
+  DRAWPATH_TYPECURVETO = 2;
+  DRAWPATH_TYPECLOSE   = 3;
+
+
 Function LineCapToString(aCap: TCanvasLineCap) : String;
 Function LineJoinToString(aJoin: TCanvasLineJoin) : String;