|
@@ -10,7 +10,7 @@ uses
|
|
|
dynlibs,
|
|
|
{$ENDIF}
|
|
|
AVL_Tree, FpImage, System.UITypes,
|
|
|
- System.Skia, Fresnel.Classes, Fresnel.DOM, Fresnel.Renderer;
|
|
|
+ System.Skia, Fresnel.Classes, Fresnel.DOM, Fresnel.Renderer, Fresnel.Images;
|
|
|
|
|
|
const
|
|
|
CSSToSkRoundRectCorner: array[TFresnelCSSCorner] of TSkRoundRectCorner = (
|
|
@@ -86,11 +86,32 @@ type
|
|
|
class function GetFont(const FontIntf: IFresnelFont; out FreSkiaFont: TFresnelSkiaFont): boolean; virtual;
|
|
|
end;
|
|
|
|
|
|
+ { TFresnelSkiaFPImage }
|
|
|
+
|
|
|
+ TFresnelSkiaFPImage = class(TFPCustomImage)
|
|
|
+ protected
|
|
|
+ FBytesPerLine: PtrUInt;
|
|
|
+ FData: PByte;
|
|
|
+ FDataSize: PtrUInt;
|
|
|
+ FSkImage: ISkImage;
|
|
|
+ function GetInternalColor(x, y: integer): TFPColor; override;
|
|
|
+ procedure SetInternalColor(x, y: integer; const Value: TFPColor); override;
|
|
|
+ function GetInternalPixel(x, y: integer): integer; override;
|
|
|
+ procedure SetInternalPixel(x, y: integer; Value: integer); override;
|
|
|
+ function GetSkImage: ISkImage; virtual;
|
|
|
+ public
|
|
|
+ constructor Create(AWidth, AHeight: integer); override;
|
|
|
+ destructor Destroy; override;
|
|
|
+ procedure SetSize(AWidth, AHeight: integer); override;
|
|
|
+ property SkImage: ISkImage read GetSkImage;
|
|
|
+ end;
|
|
|
+
|
|
|
{ TFresnelSkiaRenderer - one instance per viewport }
|
|
|
|
|
|
TFresnelSkiaRenderer = class(TFresnelRenderer)
|
|
|
private
|
|
|
FCanvas: ISkCanvas;
|
|
|
+ class constructor InitSkiaRenderer;
|
|
|
protected
|
|
|
procedure DrawElBorder(El: TFresnelElement; Params: TBorderAndBackground); override;
|
|
|
procedure DrawImage(const aLeft, aTop, aWidth, aHeight: TFresnelLength;
|
|
@@ -417,8 +438,113 @@ begin
|
|
|
end;
|
|
|
end;
|
|
|
|
|
|
+{ TFresnelSkiaFPImage }
|
|
|
+
|
|
|
+function TFresnelSkiaFPImage.GetSkImage: ISkImage;
|
|
|
+begin
|
|
|
+ if (FSkImage=nil) and (FData<>nil) then
|
|
|
+ FSkImage:=TSkImage.MakeFromRaster(TSkImageInfo.Create(Width, Height),FData,FBytesPerLine);
|
|
|
+ Result:=FSkImage;
|
|
|
+end;
|
|
|
+
|
|
|
+function TFresnelSkiaFPImage.GetInternalColor(x, y: integer): TFPColor;
|
|
|
+var
|
|
|
+ p: PByte;
|
|
|
+ v: DWORD;
|
|
|
+ c: word;
|
|
|
+begin
|
|
|
+ if (x>=0) and (y>=0) and (x<Width) and (y<Height) then
|
|
|
+ begin
|
|
|
+ p:=FData+FBytesPerLine*y+x*4;
|
|
|
+ v:=PDWord(p)^; // reading a DWord solves the big/little endianess
|
|
|
+ c:=v and $ff;
|
|
|
+ Result.Blue:=c or (c shl 8);
|
|
|
+ v:=v shr 8;
|
|
|
+ c:=v and $ff;
|
|
|
+ Result.Green:=c or (c shl 8);
|
|
|
+ v:=v shr 8;
|
|
|
+ c:=v and $ff;
|
|
|
+ Result.Red:=c or (c shl 8);
|
|
|
+ v:=v shr 8;
|
|
|
+ Result.Alpha:=c or (c shl 8);
|
|
|
+ end else begin
|
|
|
+ Result:=colBlack;
|
|
|
+ end;
|
|
|
+end;
|
|
|
+
|
|
|
+procedure TFresnelSkiaFPImage.SetInternalColor(x, y: integer;
|
|
|
+ const Value: TFPColor);
|
|
|
+var
|
|
|
+ p: PByte;
|
|
|
+ v: DWord;
|
|
|
+begin
|
|
|
+ if (x>=0) and (y>=0) and (x<Width) and (y<Height) then
|
|
|
+ begin
|
|
|
+ v:=Value.Alpha shr 8;
|
|
|
+ v:=v shl 8;
|
|
|
+ v:=v or Value.Red shr 8;
|
|
|
+ v:=v shl 8;
|
|
|
+ v:=v or Value.Green shr 8;
|
|
|
+ v:=v shl 8;
|
|
|
+ v:=v or Value.Blue shr 8;
|
|
|
+ p:=FData+FBytesPerLine*y+x*4;
|
|
|
+ PDWord(p)^:=v; // writing a DWord solves the big/little endianess
|
|
|
+ end;
|
|
|
+end;
|
|
|
+
|
|
|
+function TFresnelSkiaFPImage.GetInternalPixel(x, y: integer): integer;
|
|
|
+begin
|
|
|
+ if x=0 then exit;
|
|
|
+ if y=0 then exit;
|
|
|
+ Result:=0;
|
|
|
+end;
|
|
|
+
|
|
|
+procedure TFresnelSkiaFPImage.SetInternalPixel(x, y: integer; Value: integer);
|
|
|
+begin
|
|
|
+ if x=0 then exit;
|
|
|
+ if y=0 then exit;
|
|
|
+ if Value=0 then exit;
|
|
|
+end;
|
|
|
+
|
|
|
+constructor TFresnelSkiaFPImage.Create(AWidth, AHeight: integer);
|
|
|
+begin
|
|
|
+ inherited Create(AWidth,AHeight);
|
|
|
+end;
|
|
|
+
|
|
|
+destructor TFresnelSkiaFPImage.Destroy;
|
|
|
+begin
|
|
|
+ inherited Destroy;
|
|
|
+end;
|
|
|
+
|
|
|
+procedure TFresnelSkiaFPImage.SetSize(AWidth, AHeight: integer);
|
|
|
+begin
|
|
|
+ AWidth:=Max(0,AWidth);
|
|
|
+ AHeight:=Max(0,AHeight);
|
|
|
+ if (Width=AWidth) and (Height=AHeight) then exit;
|
|
|
+
|
|
|
+ case SkNative32ColorType of
|
|
|
+ TSkColorType.BGRA8888: ;
|
|
|
+ TSkColorType.RGBA8888: ;
|
|
|
+ else
|
|
|
+ raise EFresnel.Create('TFresnelSkiaFPImage.Resize SkNative32ColorType not supported: '+IntToStr(ord(SkNative32ColorType)));
|
|
|
+ end;
|
|
|
+
|
|
|
+ FSkImage:=nil;
|
|
|
+
|
|
|
+ inherited SetSize(AWidth, AHeight);
|
|
|
+
|
|
|
+ FBytesPerLine:=AWidth*4;
|
|
|
+ FDataSize:=FBytesPerLine*AHeight;
|
|
|
+ ReAllocMem(FData,FDataSize);
|
|
|
+end;
|
|
|
+
|
|
|
{ TFresnelSkiaRenderer }
|
|
|
|
|
|
+class constructor TFresnelSkiaRenderer.InitSkiaRenderer;
|
|
|
+begin
|
|
|
+ ImagesConfig.ImageClass := TFresnelSkiaFPImage;
|
|
|
+end;
|
|
|
+
|
|
|
procedure TFresnelSkiaRenderer.DrawElBorder(El: TFresnelElement;
|
|
|
Params: TBorderAndBackground);
|
|
|
const
|
|
@@ -515,7 +641,7 @@ begin
|
|
|
// draw border
|
|
|
if HasBorder then
|
|
|
begin
|
|
|
- // todo border-right
|
|
|
+ if not SameBorderWidth then ; // todo
|
|
|
SkPaint:=TSkPaint.Create(TSkPaintStyle.Stroke);
|
|
|
SkPaint.setColor(FPColorToSkia(Params.Color[ffsLeft]));
|
|
|
SkPaint.SetStrokeWidth(Params.Width[ffsLeft]);
|
|
@@ -533,8 +659,23 @@ end;
|
|
|
|
|
|
procedure TFresnelSkiaRenderer.DrawImage(const aLeft, aTop, aWidth,
|
|
|
aHeight: TFresnelLength; const aImage: TFPCustomImage);
|
|
|
+var
|
|
|
+ SkiaImg: TFresnelSkiaFPImage;
|
|
|
+ SkImage: ISkImage;
|
|
|
+ r: TRectF;
|
|
|
begin
|
|
|
- writeln('ToDo: TFresnelSkiaRenderer.DrawImage ',aLeft,' ',aTop,' ',aWidth,' ',aHeight,' ',aImage<>nil);
|
|
|
+ if not (aImage is TFresnelSkiaFPImage) then
|
|
|
+ begin
|
|
|
+ if aImage=nil then exit;;
|
|
|
+ raise EFresnel.Create('TFresnelSkiaRenderer.DrawImage not supported: '+aImage.ClassName);
|
|
|
+ end;
|
|
|
+ //writeln('TFresnelSkiaRenderer.DrawImage ',FloatToStr(aLeft),' ',FloatToStr(aTop),' ',FloatToStr(aWidth),' ',FloatToStr(aHeight));
|
|
|
+ SkiaImg:=TFresnelSkiaFPImage(aImage);
|
|
|
+ SkImage:=SkiaImg.SkImage;
|
|
|
+ if SkImage=nil then exit;
|
|
|
+
|
|
|
+ r:=RectF(aLeft,aTop,aLeft+aWidth,aTop+aHeight);
|
|
|
+ Canvas.DrawImageRect(SkImage,r);
|
|
|
end;
|
|
|
|
|
|
procedure TFresnelSkiaRenderer.FillRect(const aColor: TFPColor;
|