12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523 |
- {$mode objfpc}
- {$h+}
- {$modeswitch externalclass}
- {$DEFINE IMAGE_USEOSC}
- unit fresnel.pas2js.wasmapi;
- interface
- // Define this to disable API Logging altogether
- { $DEFINE NOLOGAPICALLS}
- uses classes, js, web, webassembly, wasienv, fresnel.wasm.shared;
- Const
- // These should probably move to weborworker
- MOUSE_PRIMARY = 1;
- MOUSE_SECONDARY = 2;
- MOUSE_AUXILIARY = 4;
- MOUSE_EXTRA1 = 8;
- MOUSE_EXTRA2 = 16;
- Type
- TWasmPointer = longint;
- TWasmFresnelApi = Class;
- TTimerTickCallback = Function (aTimerID : TTimerID; UserData : TWasmPointer) : Boolean;
- { TFresnelHelper }
- TFresnelHelper = Class
- Private
- class var _CurrentID : TCanvasID;
- Public
- Class function FresnelColorToHTMLColor(aColor : TCanvasColor) : string;
- Class function FresnelColorToHTMLColor(aRed, aGreen, aBlue, aAlpha: TCanvasColorComponent): string;
- class Function MouseButtonToShiftState(aButton: Integer): TShiftStateEnum;
- Class Function ShiftStateToInt(aState : TShiftState) : Integer;
- Class Function AllocateCanvasID : TCanvasID;
- end;
- TCanvasEvent = record
- CanvasID : TCanvasID;
- msg : TCanvasMessageID;
- param0 : TCanvasMessageParam;
- param1 : TCanvasMessageParam;
- param2 : TCanvasMessageParam;
- param3 : TCanvasMessageParam;
- end;
- { TCanvasReference }
- TCanvasReference = class (TObject)
- API : TWasmFresnelApi;
- CanvasID : TCanvasID;
- canvascontext : TJSCanvasRenderingContext2D;
- canvas :TJSHTMLCanvasElement;
- canvasParent :TJSHTMLElement;
- constructor create(aID : TCanvasID; aAPI : TWasmFresnelApi; aCanvas : TJSHTMLCanvasElement; aParent : TJSHTMLElement);
- private
- function DoMouseClick(aEvent: TJSEvent): boolean;
- function DoMouseDblClick(aEvent: TJSEvent): boolean;
- function DoMouseDown(aEvent: TJSEvent): boolean;
- function DoMouseUp(aEvent: TJSEvent): boolean;
- function DoMouseMove(aEvent: TJSEvent): boolean;
- function DoMouseWheel(aEvent: TJSEvent): boolean;
- function MouseToEvent(aEvent: TJSMouseEvent; aMessageID: TCanvasMessageID): TCanvasEvent;
- procedure PrepareCanvas;
- Procedure RemoveCanvas;
- Procedure SendEvent;
- end;
- { TWasmFresnelApi }
- TTimerCallback = Procedure (aCurrent,aPrevious : Double);
- TWasmFresnelApi = class(TImportExtension)
- Private
- FCanvases : TJSObject;
- FCanvasParent : TJSHTMLELement;
- FLogAPICalls : Boolean;
- FTimerID : NativeInt;
- FTimerInterval: NativeInt;
- FLastTick: TDateTime;
- Protected
- FEvents : array of TCanvasEvent;
- Procedure LogCall(const Msg : String);
- Procedure LogCall(Const Fmt : String; const Args : Array of const);
- function GetCanvas(aID : TCanvasID) : TJSCanvasRenderingContext2D;
- function GetCanvasRef(aID: TCanvasID): TCanvasReference;
- // Canvas
- function allocatecanvas(SizeX : Longint; SizeY : Longint; 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 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 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;
- 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 SetLineWidth(aID: TCanvasID; aWidth: TCanvasLineWidth): 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 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);
- // Events
- function GetEvent(aID: TWasmPointer; aMsg: TWasmPointer; Data : TWasmPointer): TCanvasError;
- function GetEventCount(aCount: TWasmPointer): TCanvasError;
- procedure DoTimerTick; virtual;
- Public
- Constructor Create(aEnv : TPas2JSWASIEnvironment); override;
- Procedure FillImportObject(aObject : TJSObject); override;
- Procedure ProcessMessages;
- Procedure StartTimerTick;
- Procedure StopTimerTick;
- Function ImportName : String; override;
- Property CanvasParent : TJSHTMLELement Read FCanvasParent Write FCanvasParent;
- Property LogAPICalls : Boolean Read FLogAPICalls Write FLogAPICalls;
- Property TimerInterval : NativeInt Read FTimerInterval Write FTimerInterval;
- end;
- Implementation
- uses sysutils;
- { ---------------------------------------------------------------------
- FresnelHelper
- ---------------------------------------------------------------------}
- class function TFresnelHelper.FresnelColorToHTMLColor(aRed,aGreen,aBlue,aAlpha: TCanvasColorComponent): string;
- 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+')';
- end;
- class function TFresnelHelper.FresnelColorToHTMLColor(aColor: TCanvasColor): string;
- Const
- Hex = '0123456789ABCDEF';
- var
- I : Integer;
- begin
- Result:='#';
- aColor:=aColor shr 8;
- for I:=1 to 6 do
- begin
- Result:=Result+Hex[(aColor and $F)+1];
- aColor:=aColor shr 4;
- end;
- end;
- class Function TFresnelHelper.ShiftStateToInt(aState : TShiftState) : Integer;
- var
- S : TShiftStateEnum;
- begin
- Result:=0;
- For S in TShiftstate do
- If (S in aState) then
- Result:=Result or (1 shl Ord(S));
- end;
- class function TFresnelHelper.MouseButtonToShiftState(aButton : Integer) : TShiftStateEnum;
- begin
- Case aButton of
- MOUSE_PRIMARY: Result:=ssLeft;
- MOUSE_SECONDARY : Result:=ssRight;
- MOUSE_AUXILIARY : Result:=ssMiddle;
- MOUSE_EXTRA1 : Result:=ssExtra1;
- MOUSE_EXTRA2 : Result:=ssExtra2;
- end;
- end;
- { ---------------------------------------------------------------------
- TCanvasReference
- ---------------------------------------------------------------------}
- procedure TWasmFresnelApi.ProcessMessages;
- var
- Callback : JSValue;
- begin
- if not assigned(InstanceExports) then
- Writeln('No instance exports !')
- else
- begin
- Callback:=InstanceExports['__fresnel_process_message'];
- if Assigned(Callback) then
- begin
- TTimerCallback(CallBack)(FLastTick,Now);
- FLastTick:=Now;
- end
- else
- Writeln('No processmessages callback !');
- end
- end;
- procedure TWasmFresnelApi.DoTimerTick;
- var
- Callback : JSValue;
- T : TDateTime;
- begin
- T:=FLastTick;
- FLastTick:=Now;
- if not assigned(InstanceExports) then
- Writeln('No instance exports !')
- else
- begin
- Callback:=InstanceExports['__fresnel_tick'];
- if Assigned(Callback) then
- begin
- TTimerCallback(CallBack)(FLastTick,T);
- end
- else
- Writeln('No tick callback !');
- end
- end;
- constructor TCanvasReference.create(aID: TCanvasID; aAPI: TWasmFresnelApi;
- aCanvas: TJSHTMLCanvasElement; aParent: TJSHTMLElement);
- begin
- Canvas:=aCanvas;
- canvasParent:=aParent;
- API:=aAPI;
- CanvasID:=aID;
- PrepareCanvas;
- end;
- procedure TCanvasReference.PrepareCanvas;
- begin
- CanvasContext:=TJSCanvasRenderingContext2D(Canvas.getcontext('2d'));
- Canvas.AddEventListener('mousedown',@DoMouseDown);
- Canvas.AddEventListener('mouseup',@DoMouseUp);
- Canvas.AddEventListener('mousemove',@DoMouseMove);
- Canvas.AddEventListener('click',@DoMouseClick);
- Canvas.AddEventListener('dblclick',@DoMouseDblClick);
- Canvas.AddEventListener('scroll',@DoMouseWheel);
- end;
- procedure TCanvasReference.RemoveCanvas;
- begin
- CanvasParent.removeChild(Canvas);
- Canvas:=Nil;
- CanvasParent:=nil;
- canvascontext:=nil;
- end;
- procedure TCanvasReference.SendEvent;
- begin
- API.ProcessMessages;
- end;
- function TCanvasReference.MouseToEvent(aEvent : TJSMouseEvent;aMessageID : TCanvasMessageID) : TCanvasEvent;
- var
- State : TShiftState;
- Procedure Check(aButton : Integer);
- begin
- if (aEvent.buttons and aButton)<>0 then
- include(State,TFresnelHelper.MouseButtonToShiftState(aButton));
- end;
- begin
- Result.CanvasID:=Self.CanvasID;
- Result.msg:=aMessageID;
- Result.param0:=Round(aEvent.OffsetX);
- Result.param1:=Round(aEvent.OffsetY);
- State:=[];
- Check(MOUSE_PRIMARY);
- Check(MOUSE_SECONDARY);
- Check(MOUSE_AUXILIARY);
- Check(MOUSE_EXTRA1);
- Check(MOUSE_EXTRA2);
- If aEvent.altKey then
- Include(State,ssAlt);
- If aEvent.ctrlKey then
- Include(State,ssCtrl);
- If aEvent.shiftKey then
- Include(State,ssShift);
- if aEvent.metaKey then
- Include(State,ssMeta);
- Result.Param2:=TFresnelHelper.ShiftStateToInt(State);
- end;
- function TCanvasReference.DoMouseDown(aEvent: TJSEvent): boolean;
- var
- Evt : TJSMouseEvent absolute aEvent;
- begin
- Result:=True;
- TJSArray(API.FEvents).Push(MouseToEvent(evt,WASMSG_MOUSEDOWN));
- SendEvent;
- end;
- function TCanvasReference.DoMouseMove(aEvent: TJSEvent): boolean;
- var
- Evt : TJSMouseEvent absolute aEvent;
- begin
- Result:=True;
- TJSArray(API.FEvents).Push(MouseToEvent(evt,WASMSG_MOVE));
- SendEvent;
- end;
- function TCanvasReference.DoMouseWheel(aEvent: TJSEvent): boolean;
- var
- JSEvt : TJSWheelEvent absolute aEvent;
- CanvasEvt : TCanvasEvent;
- begin
- Result:=True;
- CanvasEvt:=MouseToEvent(JSevt,WASMSG_WHEELY);
- Case JSEvt.deltaMode of
- 0 : CanvasEvt.Param3:=Round(JSEvt.deltaY);
- 1 : CanvasEvt.Param3:=Round(JSEvt.deltaY*12); // arbitrary
- 2 : CanvasEvt.Param3:=Round(JSEvt.deltaY*600); // arbitrary
- end;
- TJSArray(API.FEvents).Push(CanvasEvt);
- SendEvent;
- end;
- function TCanvasReference.DoMouseClick(aEvent: TJSEvent): boolean;
- var
- Evt : TJSMouseEvent absolute aEvent;
- begin
- Result:=True;
- TJSArray(API.FEvents).Push(MouseToEvent(evt,WASMSG_CLICK));
- SendEvent;
- end;
- function TCanvasReference.DoMouseDblClick(aEvent: TJSEvent): boolean;
- var
- Evt : TJSMouseEvent absolute aEvent;
- begin
- Result:=True;
- TJSArray(API.FEvents).Push(MouseToEvent(evt,WASMSG_DBLCLICK));
- SendEvent;
- end;
- function TCanvasReference.DoMouseUp(aEvent: TJSEvent): boolean;
- var
- Evt : TJSMouseEvent absolute aEvent;
- begin
- Result:=True;
- TJSArray(API.FEvents).Push(MouseToEvent(evt,WASMSG_MOUSEUP));
- SendEvent;
- end;
- constructor TWasmFresnelApi.Create(aEnv: TPas2JSWASIEnvironment);
- begin
- Inherited Create(aEnv);
- FCanvases:=TJSObject.New();
- FLogAPICalls:=True;
- FTimerInterval:=10;
- FLastTick:=Now;
- end;
- function TWasmFresnelApi.ImportName: String;
- begin
- Result:='fresnel_api';
- end;
- function TWasmFresnelApi.GetCanvasRef(aID : TCanvasID) : TCanvasReference;
- var
- JS : JSValue;
- begin
- JS:=FCanvases[IntTostr(AID)];
- if IsObject(JS) then
- Result:= TCanvasReference(JS)
- else
- Result:=nil;
- end;
- class function TFresnelHelper.AllocateCanvasID: TCanvasID;
- begin
- Inc(_CurrentID);
- Result:=_CurrentID;
- end;
- procedure TWasmFresnelApi.LogCall(const Msg: String);
- begin
- {$IFNDEF NOLOGAPICALLS}
- If not LogAPICalls then exit;
- Writeln(Msg);
- {$ENDIF}
- end;
- procedure TWasmFresnelApi.LogCall(const Fmt: String; const Args: array of const);
- begin
- {$IFNDEF NOLOGAPICALLS}
- If not LogAPICalls then exit;
- Writeln(Format(Fmt,Args));
- {$ENDIF}
- end;
- function TWasmFresnelApi.GetCanvas(aID : TCanvasID) : TJSCanvasRenderingContext2D;
- Var
- Ref : TCanvasReference;
- begin
- Ref:=GetCanvasRef(aID);
- if Assigned(Ref) then
- Result:= Ref.canvascontext
- else
- begin
- Writeln('Unknown canvas : ',aID);
- Result:=Nil;
- end;
- end;
- procedure TWasmFresnelApi.FillImportObject(aObject: TJSObject);
- begin
- // Canvas
- aObject['canvas_allocate']:=@AllocateCanvas;
- aObject['canvas_getbyid']:=@getcanvasbyid;
- aObject['canvas_getsizes']:=@getcanvassizes;
- aObject['canvas_moveto']:=@moveto;
- aObject['canvas_lineto']:=@LineTo;
- aObject['canvas_stroke']:=@stroke;
- aObject['canvas_beginpath']:=@beginpath;
- aObject['canvas_arc']:=@arc;
- aObject['canvas_fillrect']:=@fillrect;
- aObject['canvas_strokerect']:=@strokerect;
- aObject['canvas_clearrect']:=@clearrect;
- aObject['canvas_stroketext']:=@StrokeText;
- aObject['canvas_filltext']:=@FillText;
- aObject['canvas_set_fillstyle']:=@SetFillStyle;
- aObject['canvas_linear_gradient_fillstyle']:=@SetLinearGradientFillStyle;
- aObject['canvas_image_fillstyle']:=@SetImageFillStyle;
- aObject['canvas_set_strokestyle']:=@SetStrokeStyle;
- aObject['canvas_set_linewidth']:=@SetLineWidth;
- aObject['canvas_set_linecap']:=@SetLineCap;
- aObject['canvas_set_linejoin']:=@SetLineJoin;
- aObject['canvas_set_linemiterlimit']:=@SetLineMiterLimit;
- aObject['canvas_set_linedash']:=@SetLineDash;
- aObject['canvas_draw_image']:=@DrawImage;
- aObject['canvas_set_font']:=@SetFont;
- 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;
- // Event
- aObject['event_get']:=@GetEvent;
- aObject['event_count']:=@GetEventCount;
- end;
- procedure TWasmFresnelApi.StartTimerTick;
- begin
- FTimerID:=Window.setInterval(@DoTimerTick,FTimerInterval);
- end;
- procedure TWasmFresnelApi.StopTimerTick;
- begin
- Window.clearInterval(FTimerID);
- end;
- function TWasmFresnelApi.GetCanvasSizes(aID: TCanvasID; aWidth, aHeight: TWasmPointer): TCanvasError;
- var
- Ref: TCanvasReference;
- v : TJSDataView;
- begin
- {$IFNDEF NOLOGAPICALLS}
- If LogAPICalls then
- begin
- LogCall('Canvas.GetCanvasSizes(%d,[%x],[%x])',[aID,aWidth,aHeight]);
- end;
- {$ENDIF}
- 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;
- var
- Canv : TJSCanvasRenderingContext2D;
- S : String;
- begin
- {$IFNDEF NOLOGAPICALLS}
- If LogAPICalls then
- begin
- LogCall('Canvas.SetFillStyle(%d,%d,%d,%d,%d)',[aID,aRed,aGreen,aBlue,aAlpha]);
- end;
- {$ENDIF}
- Canv:=GetCanvas(aID);
- if Not Assigned(Canv) then
- Exit(ECANVAS_NOCANVAS);
- S:=TFresnelHelper.FresnelColorToHTMLColor(aRed,aGreen,aBlue,aAlpha);
- // Writeln('Fill: ',S);
- Canv.fillStyle:=S;
- 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;
- var
- I,P : Longint;
- Red,Green,Blue,Alpha: Longint;
- offset : double;
- G : TJSCanvasGradient;
- Canv : TJSCanvasRenderingContext2D;
- V : TJSDataView;
- S : String;
- function GetLongint: longint;
- begin
- Result:=V.getInt32(P,Env.IsLittleEndian);
- Inc(P,4);
- end;
- begin
- {$IFNDEF NOLOGAPICALLS}
- If LogAPICalls then
- begin
- LogCall('Canvas.SetLinearGradientFillStyle(%d,(%d,%d),(%d,%d),%d,[%x])',[aID,aStartX, aStartY, aEndX, aEndY, aColorPointCount,aColorPoints]);
- end;
- {$ENDIF}
- Canv:=GetCanvas(aID);
- if Not Assigned(Canv) then
- Exit(ECANVAS_NOCANVAS);
- G:=Canv.createLinearGradient(aStartX,aStartY,aEndX,aEndY);
- V:=getModuleMemoryDataView;
- P:=aColorPoints;
- For I:=0 to aColorPointCount-1 do
- begin
- Red:=GetLongint;
- Green:=GetLongint;
- Blue:=GetLongint;
- Alpha:=GetLongint;
- offset:=GetLongint/10000;
- S:=TFresnelHelper.FresnelColorToHTMLColor(Red,Green,Blue,Alpha);
- G.addColorStop(offset,S);
- end;
- Canv.fillStyleAsGradient:=G;
- Exit(ECANVAS_SUCCESS);
- end;
- function TWasmFresnelApi.SetImageFillStyle(aID: TCanvasID; Flags: Longint;
- aImageWidth, aImageHeight: Longint; aImageData: TWasmPointer): TCanvasError;
- var
- OSC : TJSHTMLOffscreenCanvasElement;
- ImgData : TJSImageData;
- // OSCImgBitmap : TJSImageBitmap;
- Canv,Canv2 : TJSCanvasRenderingContext2D;
- D : TJSUint8ClampedArray;
- V : TJSDataView;
- S : String;
- begin
- {$IFNDEF NOLOGAPICALLS}
- If LogAPICalls then
- begin
- LogCall('Canvas.SetImageFillStyle(%d,%d,(%d,%d),[%x])',[aID,flags,aImageWidth,aImageHeight,aImageData]);
- end;
- {$ENDIF}
- Canv:=GetCanvas(aID);
- if Not Assigned(Canv) then
- Exit(ECANVAS_NOCANVAS);
- V:=getModuleMemoryDataView;
- D:=TJSUint8ClampedArray.New(V.Buffer,aImageData,aImageWidth*aImageWidth*4);
- ImgData:=TJSImageData.new(D,aImageWidth,aImageWidth);
- OSC:=TJSHTMLOffscreenCanvasElement.New(aImageWidth,aImageHeight);
- Canv2:=OSC.getContextAs2DContext('2d');
- Canv2.clearRect(0,0,aImageWidth,aImageHeight);
- Canv2.putImageData(ImgData,0,0);
- Case flags and 3 of
- IMAGEFILLSTYLE_NOREPEAT : s:='no-repeat';
- IMAGEFILLSTYLE_REPEAT : s:='repeat';
- IMAGEFILLSTYLE_REPEATX : s:='repeat-x';
- IMAGEFILLSTYLE_REPEATY : s:='repeat-y';
- end;
- Canv.fillStyleAsPattern:=Canv.createPattern(OSC,S);
- end;
- function TWasmFresnelApi.SetStrokeStyle(aID: TCanvasID; aRed, aGreen, aBlue, aAlpha: TCanvasColorComponent): TCanvasError;
- var
- Canv : TJSCanvasRenderingContext2D;
- S : String;
- begin
- {$IFNDEF NOLOGAPICALLS}
- If LogAPICalls then
- begin
- LogCall('Canvas.SetStrokeStyle(%d,%d,%d,%d,%d)',[aID,aRed,aGreen,aBlue,aAlpha]);
- end;
- {$ENDIF}
- Canv:=GetCanvas(aID);
- if Not Assigned(Canv) then
- Exit(ECANVAS_NOCANVAS);
- S:=TFresnelHelper.FresnelColorToHTMLColor(aRed,aGreen,aBlue,aAlpha);
- Canv.StrokeStyle:=S;
- Result:=ECANVAS_SUCCESS;
- end;
- function TWasmFresnelApi.DrawImage(aID: TCanvasID; aX, aY, aWidth, aHeight, aImageWidth, aImageHeight: Longint;
- aImageData: TWasmPointer): TCanvasError;
- var
- V : TJSDataView;
- D : TJSUint8ClampedArray;
- ImgData : TJSImageData;
- Canv : TJSCanvasRenderingContext2D;
- {$IFDEF IMAGE_USEOSC}
- Canv2 : TJSCanvasRenderingContext2D;
- OSC : TJSHTMLOffscreenCanvasElement;
- {$ENDIF}
- begin
- {$IFNDEF NOLOGAPICALLS}
- If LogAPICalls then
- begin
- LogCall('Canvas.DrawImage(%d,%d,%d,%d,%d,%d,%d)',[aID,aX,aY,aWidth,aHeight,aImageWidth,aImageHeight]);
- end;
- {$ENDIF}
- Canv:=GetCanvas(aID);
- if Not Assigned(Canv) then
- Exit(ECANVAS_NOCANVAS);
- V:=getModuleMemoryDataView;
- D:=TJSUint8ClampedArray.New(V.Buffer,aImageData,aImageWidth*aImageWidth*4);
- ImgData:=TJSImageData.new(D,aImageWidth,aImageWidth);
- {$IFDEF IMAGE_USEOSC}
- OSC:=TJSHTMLOffscreenCanvasElement.New(aImageWidth,aImageHeight);
- Canv2:=OSC.getContextAs2DContext('2d');
- Canv2.clearRect(0,0,aImageWidth,aImageHeight);
- Canv2.putImageData(ImgData,0,0);
- Canv.drawImage(OSC,aX,aY,aWidth,aHeight);
- {$ELSE}
- Window.createImageBitmap(ImgData)._then(
- function (res : jsvalue) : JSValue
- var
- ImgBitmap : TJSImageBitmap absolute res;
- begin
- Canv.drawImage(ImgBitmap,aX,aY,aWidth,aHeight);
- end);
- {$ENDIF}
- Result:=ECANVAS_SUCCESS;
- end;
- function TWasmFresnelApi.SetFont(aID: TCanvasID; aFontName: TWasmPointer; aFontNameLen: integer): TCanvasError;
- var
- S : String;
- Canv:TJSCanvasRenderingContext2D;
- begin
- S:=Env.GetUTF8StringFromMem(aFontName,aFontNameLen);
- {$IFNDEF NOLOGAPICALLS}
- If LogAPICalls then
- begin
- LogCall('Canvas.SetFont(%d,"%s")',[aID,S]);
- end;
- {$ENDIF}
- Canv:=GetCanvas(aID);
- if Not Assigned(Canv) then
- Exit(ECANVAS_NOCANVAS);
- Canv.font:=S;
- Result:=ECANVAS_SUCCESS;
- end;
- function TWasmFresnelApi.MeasureText(aID: TCanvasID; aText: TWasmPointer; aTextLen: integer; aWidth, aHeight: Longint
- ): TCanvasError;
- var
- S : String;
- Canv:TJSCanvasRenderingContext2D;
- M : TJSTextMetrics;
- V : TJSDataView;
- W,H : Double;
- begin
- S:=Env.GetUTF8StringFromMem(aText,aTextLen);
- {$IFNDEF NOLOGAPICALLS}
- If LogAPICalls then
- begin
- LogCall('Canvas.MeasureText(%d,"%s")',[aID,S]);
- end;
- {$ENDIF}
- Canv:=GetCanvas(aID);
- if Not Assigned(Canv) then
- Exit(ECANVAS_NOCANVAS);
- M:=Canv.measureText(S);
- W:=M.width;
- H:=M.actualBoundingBoxAscent +M.actualBoundingBoxDescent;
- V:=getModuleMemoryDataView;
- {$IFNDEF NOLOGAPICALLS}
- If LogAPICalls then
- begin
- LogCall('Canvas.MeasureText(%d,"%s") : [%g,%g]',[aID,S,W,H]);
- end;
- {$ENDIF}
-
- v.setint32(aWidth,Round(W),env.IsLittleEndian);
- v.setint32(aHeight,Round(H),env.IsLittleEndian);
- Result:=ECANVAS_SUCCESS;
- end;
- function TWasmFresnelApi.SetTextShadowParams (aID : TCanvasID; aOffsetX,aOffsetY,aRadius : Longint; aRed,aGreen,aBlue,aAlpha : TCanvasColorComponent): TCanvasError;
- var
- Canv:TJSCanvasRenderingContext2D;
- 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)]);
- end;
- {$ENDIF}
- Canv:=GetCanvas(aID);
- if Not Assigned(Canv) then
- Exit(ECANVAS_NOCANVAS);
- Canv.shadowOffsetX:=aOffsetX;
- Canv.shadowOffsetY:=aOffsetY;
- Canv.shadowBlur:=FresnelUnScale(aRadius);
- Canv.shadowColor:=TFresnelHelper.FresnelColorToHTMLColor(aRed,aGreen,aBlue,aAlpha);
- 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
- aTimerID : TTimerID;
- CallBack:jsvalue;
- Procedure HandleTimer;
- var
- Continue : boolean;
- begin
- // The instance/timer could have disappeared
- Callback:=InstanceExports['__fresnel_timer_tick'];
- Continue:=Assigned(Callback);
- if Continue then
- Continue:=TTimerTickCallback(CallBack)(aTimerID,userData)
- else
- Writeln('No more tick callback !');
- if not Continue then
- DeAllocateTimer(aTimerID);
- end;
- begin
- Callback:=InstanceExports['__fresnel_timer_tick'];
- if Not Assigned(Callback) then
- Exit(0);
- aTimerID:=Window.setInterval(@HandleTimer,aInterval);
- Result:=aTimerID;
- end;
- procedure TWasmFresnelApi.DeallocateTimer(timerid: TTimerID);
- begin
- window.clearTimeout(TimerID);
- end;
- function TWasmFresnelApi.SetLineWidth(aID : TCanvasID;aWidth : TCanvasLineWidth): TCanvasError;
- var
- Canv:TJSCanvasRenderingContext2D;
- begin
- {$IFNDEF NOLOGAPICALLS}
- If LogAPICalls then
- begin
- LogCall('Canvas.SetLineWidth(%d,%g)',[aID,FresnelUnscale(aWidth)]);
- end;
- {$ENDIF}
- Canv:=GetCanvas(aID);
- if Not Assigned(Canv) then
- Exit(ECANVAS_NOCANVAS);
- Canv.LineWidth:=FresnelUnScale(aWidth);
- Result:=ECANVAS_SUCCESS;
- end;
- function TWasmFresnelApi.SetLineCap(aID : TCanvasID; aCap : TCanvasLinecap): TCanvasError;
- var
- Canv:TJSCanvasRenderingContext2D;
- S : String;
- begin
- S:=LineCapToString(aCap);
- {$IFNDEF NOLOGAPICALLS}
- If LogAPICalls then
- begin
- LogCall('Canvas.SetLineCap(%d,%s)',[aID,S]);
- end;
- {$ENDIF}
- Canv:=GetCanvas(aID);
- if Not Assigned(Canv) then
- Exit(ECANVAS_NOCANVAS);
- Canv.lineCap:=S;
- Result:=ECANVAS_SUCCESS;
- end;
- function TWasmFresnelApi.SetLineJoin(aID : TCanvasID; aJoin : TCanvasLineJoin): TCanvasError;
- var
- Canv:TJSCanvasRenderingContext2D;
- S : String;
- begin
- S:=LineJoinToString(aJoin);
- {$IFNDEF NOLOGAPICALLS}
- If LogAPICalls then
- begin
- LogCall('Canvas.SetLineJoin(%d,%s)',[aID,S]);
- end;
- {$ENDIF}
- Canv:=GetCanvas(aID);
- if Not Assigned(Canv) then
- Exit(ECANVAS_NOCANVAS);
- Canv.lineJoin:=S;
- Result:=ECANVAS_SUCCESS;
- end;
- function TWasmFresnelApi.SetLineMiterLimit(aID : TCanvasID; aWidth : TCanvasLineMiterLimit): TCanvasError;
- var
- Canv:TJSCanvasRenderingContext2D;
- begin
- {$IFNDEF NOLOGAPICALLS}
- If LogAPICalls then
- begin
- LogCall('Canvas.SetLineMiterLimit(%d,%d)',[aID,aWidth]);
- end;
- {$ENDIF}
- Canv:=GetCanvas(aID);
- if Not Assigned(Canv) then
- Exit(ECANVAS_NOCANVAS);
- Canv.miterLimit:=FresnelUnscale(aWidth);
- Result:=ECANVAS_SUCCESS;
- LogCall('Canvas.SetLineMiterLimit not implemented');
- end;
- function TWasmFresnelApi.SetLineDash(aID: TCanvasID; aOffset: Longint;
- aPatternCount: longint; aPattern: TWasmPointer): TCanvasError;
- var
- Dashes : TJSArray;
- V : TJSDataView;
- I : Integer;
- P : TWasmPointer;
- Canv:TJSCanvasRenderingContext2D;
- begin
- {$IFNDEF NOLOGAPICALLS}
- If LogAPICalls then
- begin
- LogCall('Canvas.SetLineDash(%d,%g,%d,[%x])',[aID,FresnelUnscale(aOffset),aPatternCount,aPattern]);
- end;
- {$ENDIF}
- Canv:=GetCanvas(aID);
- if Not Assigned(Canv) then
- Exit(ECANVAS_NOCANVAS);
- Dashes:=TJSArray.New;
- if aPatternCount>0 then
- begin
- V:=getModuleMemoryDataView;
- P:=aPattern;
- for I:=0 to APatternCount-1 do
- begin
- Dashes.Push(FresnelUnScale(v.Getint32(P,env.IsLittleEndian)));
- Inc(P,4);
- end;
- end;
- Canv.lineDashOffset:=FresnelUnscale(aOffset);
- Canv.setLineDash(Dashes);
- end;
- { ---------------------------------------------------------------------
- Event API
- ---------------------------------------------------------------------}
- // note that the events are for a single canvas !
- function TWasmFresnelApi.GetEvent(aID: TWasmPointer; aMsg: TWasmPointer; Data: TWasmPointer): TCanvasError;
- const
- Int32Size = 4;
- var
- V : TJSDataView;
- Evt : TCanvasEvent;
- begin
- if Length(FEvents)=0 then
- Exit(EWASMEVENT_NOEVENT);
- Evt:=FEvents[0];
- Delete(FEvents,0,1);
- V:=getModuleMemoryDataView;
- v.setint32(aID,Evt.CanvasID,env.IsLittleEndian);
- v.setint32(aMsg,Evt.Msg,env.IsLittleEndian);
- v.setint32(Data,Evt.param0,env.IsLittleEndian);
- inc(Data,Int32Size);
- v.setint32(Data,Evt.param1,env.IsLittleEndian);
- inc(Data,Int32Size);
- v.setint32(Data,Evt.param2,env.IsLittleEndian);
- inc(Data,Int32Size);
- v.setint32(Data,Evt.param3,env.IsLittleEndian);
- Result:=EWASMEVENT_SUCCESS;
- end;
- function TWasmFresnelApi.GetEventCount(aCount: TWasmPointer): TCanvasError;
- var
- V : TJSDataView;
- begin
- V:=getModuleMemoryDataView;
- v.setint32(aCount,Length(FEvents),env.IsLittleEndian);
- Result:=EWASMEVENT_SUCCESS;
- end;
- function TWasmFresnelApi.getcanvasbyid(aCanvasElementID: TWasmPointer; aElementIDLen: Longint; aID: TWasmPointer): TCanvasError;
- var
- S : String;
- El : TJSElement;
- V : TJSDataView;
- aCanvasID : TCanvasID;
- begin
- S:=Env.GetUTF8StringFromMem(aCanvasElementID,aElementIDLen);
- {$IFNDEF NOLOGAPICALLS}
- If LogAPICalls then
- begin
- LogCall('Canvas.GetCanvasByID(''%s'')',[S]);
- end;
- {$ENDIF}
- el:=Nil;
- if (S<>'') then
- El:=Window.Document.getElementById(S);
- if (El=Nil) then
- Exit(ECANVAS_NOCANVAS);
- if not Sametext(el.tagName,'CANVAS') then
- Exit(ECANVAS_NOCANVAS);
- V:=getModuleMemoryDataView;
- aCanvasID:=TFresnelHelper.AllocateCanvasID;
- FCanvases[IntToStr(aCanvasID)]:=TCanvasReference.Create(aID,Self,TJSHTMLCanvasElement(el),TJSHTMLElement(el.parentElement));
- v.setUint32(aID, aCanvasID, env.IsLittleEndian);
- Result:=ECANVAS_SUCCESS;
- end;
- function TWasmFresnelApi.deallocatecanvas(aID: TCanvasID): TCanvasError;
- var
- Ref : TCanvasReference;
- begin
- Ref:=GetCanvasRef(aID);
- if not assigned(Ref) then
- Exit(ECANVAS_NOCANVAS);
- Ref.RemoveCanvas;
- FCanvases[IntToStr(aID)]:=Undefined;
- Ref.Free;
- Result:=ECANVAS_SUCCESS;
- end;
- function TWasmFresnelApi.allocatecanvas(SizeX: Longint; SizeY: Longint;
- aID: TWasmPointer): TCanvasError;
- Var
- CParent : TJSHTMLElement;
- Canv : TJSHTMLCanvasElement;
- Ref : TCanvasReference;
- V : TJSDataView;
- aCanvasID : TCanvasID;
- SID: String;
-
- begin
- {$IFNDEF NOLOGAPICALLS}
- If LogAPICalls then
- LogCall('Canvas.AllocateCanvas(%d,%d)',[SizeX,SizeY]);
- {$ENDIF}
- aCanvasID:=TFresnelHelper.AllocateCanvasID;
- sID:=IntToStr(aCanvasID);
- CParent:=TJSHTMLElement(document.createElement('div'));
- CParent.id:='ffp'+sID;
- CanvasParent.AppendChild(CParent);
- Canv:=TJSHTMLCanvasElement(document.createElement('CANVAS'));
- Canv.id:='ffc'+sID;
- Canv.width:=SizeX;
- Canv.height:=SizeY;
- CParent.AppendChild(Canv);
- V:=getModuleMemoryDataView;
- Ref:=TCanvasReference.Create(aCanvasID,Self,Canv,CParent);
- Ref.canvascontext.textBaseline:='top';
- FCanvases[sID]:=Ref;
- v.setUint32(aID, aCanvasID, env.IsLittleEndian);
- Result:=ECANVAS_SUCCESS;
- end;
- function TWasmFresnelApi.moveto(aID : TCanvasID; X : Longint;Y : Longint): TCanvasError;
- Var
- C : TJSCanvasRenderingContext2D;
- begin
- {$IFNDEF NOLOGAPICALLS}
- If LogAPICalls then
- LogCall('Canvas.MoveTo(%d,%d,%d)',[aID,X,Y]);
- {$ENDIF}
- Result:=ECANVAS_NOCANVAS;
- C:=GetCanvas(aID);
- if Assigned(C) then
- begin
- C.moveto(X,Y);
- Result:=ECANVAS_SUCCESS;
- end;
- end;
- function TWasmFresnelApi.lineto(aID : TCanvasID;X : Longint; Y : Longint ): TCanvasError;
- Var
- C : TJSCanvasRenderingContext2D;
- begin
- {$IFNDEF NOLOGAPICALLS}
- If LogAPICalls then
- LogCall('Canvas.LineTo(%d,%d,%d)',[aID,X,Y]);
- {$ENDIF}
- Result:=ECANVAS_NOCANVAS;
- C:=GetCanvas(aID);
- if Assigned(C) then
- begin
- C.lineto(X,Y);
- Result:=ECANVAS_SUCCESS;
- end;
- end;
- function TWasmFresnelApi.stroke(aID : TCanvasID): TCanvasError;
- Var
- C : TJSCanvasRenderingContext2D;
- begin
- {$IFNDEF NOLOGAPICALLS}
- If LogAPICalls then
- LogCall('Canvas.Stroke(%d)',[aID]);
- {$ENDIF}
- Result:=ECANVAS_NOCANVAS;
- C:=GetCanvas(aID);
- if Assigned(C) then
- begin
- C.Stroke;
- Result:=ECANVAS_SUCCESS;
- end;
- end;
- function TWasmFresnelApi.beginpath(aID : TCanvasID): TCanvasError;
- Var
- C : TJSCanvasRenderingContext2D;
- begin
- {$IFNDEF NOLOGAPICALLS}
- If LogAPICalls then
- LogCall('Canvas.BeginPath(%d)',[aID]);
- {$ENDIF}
- Result:=ECANVAS_NOCANVAS;
- C:=GetCanvas(aID);
- if Assigned(C) then
- begin
- C.beginPath;
- Result:=ECANVAS_SUCCESS;
- end;
- end;
- function TWasmFresnelApi.arc(aID: TCanvasID; X: Longint; Y: Longint; RadiusX,
- RadiusY: Longint; StartAngle: Longint; EndAngle: Longint; Rotate: Longint;
- Flags: Longint): TCanvasError;
- Var
- C : TJSCanvasRenderingContext2D;
- 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)]);
- {$ENDIF}
- Result:=ECANVAS_NOCANVAS;
- C:=GetCanvas(aID);
- if Assigned(C) then
- begin
- C.beginPath;
- if RadiusX=RadiusY then
- C.Arc(X,y,RadiusX,FresnelUnscale(Startangle),FresnelUnscale(EndAngle))
- else
- C.Ellipse(X,y,RadiusX,RadiusY,FresnelUnScale(Rotate),FresnelUnscale(Startangle),FresnelUnscale(EndAngle));
- if ((Flags and ARC_FILL)<>0) then
- C.fill();
- C.stroke();
- Result:=ECANVAS_SUCCESS;
- end;
- end;
- function TWasmFresnelApi.fillrect(aID : TCanvasID; X : Longint; Y : Longint; Width : Longint; Height : Longint): TCanvasError;
- Var
- C : TJSCanvasRenderingContext2D;
- begin
- {$IFNDEF NOLOGAPICALLS}
- If LogAPICalls then
- LogCall('Canvas.FillRect(%d,%d,%d,%d,%d)',[aID,X,Y,Width,Height]);
- {$ENDIF}
- Result:=ECANVAS_NOCANVAS;
- C:=GetCanvas(aID);
- if Assigned(C) then
- begin
- C.FillRect(X,y,width,Height);
- Result:=ECANVAS_SUCCESS;
- end;
- end;
- function TWasmFresnelApi.strokerect(aID : TCanvasID;X : Longint;Y : Longint; Width : Longint; Height : Longint ): TCanvasError;
- Var
- C : TJSCanvasRenderingContext2D;
- begin
- {$IFNDEF NOLOGAPICALLS}
- If LogAPICalls then
- LogCall('Canvas.StrokeRect(%d,%d,%d,%d,%d)',[aID,X,Y,Width,Height]);
- {$ENDIF}
- Result:=ECANVAS_NOCANVAS;
- C:=GetCanvas(aID);
- if Assigned(C) then
- begin
- C.StrokeRect(X,Y,Width,Height);
- Result:=ECANVAS_SUCCESS;
- end;
- end;
- function TWasmFresnelApi.clearrect(aID : TCanvasID;X : Longint;Y : Longint;Width : Longint; Height : Longint ): TCanvasError;
- Var
- C : TJSCanvasRenderingContext2D;
- begin
- {$IFNDEF NOLOGAPICALLS}
- If LogAPICalls then
- LogCall('Canvas.ClearRect(%d,%d,%d,%d,%d)',[aID,X,Y,Width,Height]);
- {$ENDIF}
- Result:=ECANVAS_NOCANVAS;
- C:=GetCanvas(aID);
- if Assigned(C) then
- begin
- C.ClearRect(X,Y,Width,Height);
- Result:=ECANVAS_SUCCESS;
- end;
- end;
- function TWasmFresnelApi.RoundRect(aID: TCanvasID; Flags: Longint; Data: TWasmPointer): TCanvasError;
- Var
- C : TJSCanvasRenderingContext2D;
- V : TJSDataView;
- X,Y,W,H : TFresnelFloat;
- Radii : TJSArray;
- Fill : Boolean;
- function GetElement(aOffset : Longint) : TFresnelFloat;
- begin
- Result:=FresnelUnScale(V.getInt32(Data+(aOffset*4),Env.IsLittleEndian));
- end;
- Procedure AddRadius(aRX,aRY : Double);
- begin
- Radii.Push(New(['x',aRX,'y',aRY]))
- end;
- begin
- {$IFNDEF NOLOGAPICALLS}
- If LogAPICalls then
- LogCall('Canvas.RoundRect(%d,%d,[%d])',[aID,Flags,Data]);
- {$ENDIF}
- C:=GetCanvas(aID);
- if not Assigned(C) then
- Exit(ECANVAS_NOCANVAS);
- V:=getModuleMemoryDataView;
- X:=GetElement(ROUNDRECT_BOXTOPLEFTX);
- Y:=GetElement(ROUNDRECT_BOXTOPLEFTY);
- W:=GetElement(ROUNDRECT_BOXBOTTOMRIGHTX)-X;
- H:=GetElement(ROUNDRECT_BOXBOTTOMRIGHTY)-Y;
- Fill:=(Flags and ROUNDRECT_FLAG_FILL)<>0;
- Radii:=TJSArray.New;
- AddRadius(GetElement(ROUNDRECT_RADIITOPLEFTX),GetElement(ROUNDRECT_RADIITOPLEFTY));
- AddRadius(GetElement(ROUNDRECT_RADIITOPRIGHTX),GetElement(ROUNDRECT_RADIITOPRIGHTY));
- AddRadius(GetElement(ROUNDRECT_RADIIBOTTOMRIGHTX),GetElement(ROUNDRECT_RADIIBOTTOMRIGHTY));
- AddRadius(GetElement(ROUNDRECT_RADIIBOTTOMLEFTX),GetElement(ROUNDRECT_RADIIBOTTOMLEFTY));
- C.BeginPath;
- C.roundRect(X,Y,W,H,Radii);
- if Fill then
- C.fill;
- C.stroke();
- Result:=ECANVAS_SUCCESS;
- end;
- function TWasmFresnelApi.StrokeText(aID: TCanvasID; X: Longint; Y: Longint; aText: TWasmPointer; aTextLen: Longint): TCanvasError;
- Var
- C : TJSCanvasRenderingContext2D;
- S : String;
- begin
- S:=Env.GetUTF8StringFromMem(aText,aTextLen);
- {$IFNDEF NOLOGAPICALLS}
- If LogAPICalls then
- begin
- LogCall('Canvas.StrokeText(%d,%d,%d,''%s'')',[aID,X,Y,S]);
- end;
- {$ENDIF}
- Result:=ECANVAS_NOCANVAS;
- C:=GetCanvas(aID);
- if Assigned(C) then
- begin
- C.StrokeText(S,X,Y);
- Result:=ECANVAS_SUCCESS;
- end;
- end;
- function TWasmFresnelApi.FillText(aID: TCanvasID; X: Longint; Y: Longint; aText: TWasmPointer; aTextLen: Longint): TCanvasError;
- Var
- C : TJSCanvasRenderingContext2D;
- S : String;
- begin
- S:=Env.GetUTF8StringFromMem(aText,aTextLen);
- {$IFNDEF NOLOGAPICALLS}
- If LogAPICalls then
- begin
- LogCall('Canvas.FillText(%d,%d,%d,''%s'')',[aID,X,Y,S]);
- end;
- {$ENDIF}
- Result:=ECANVAS_NOCANVAS;
- C:=GetCanvas(aID);
- if Assigned(C) then
- begin
- S:=Env.GetUTF8StringFromMem(aText,aTextLen);
- C.FillText(S,X,Y);
- Result:=ECANVAS_SUCCESS;
- end;
- end;
- end.
|