Jump to content

vfbb

Members
  • Content Count

    266
  • Joined

  • Last visited

  • Days Won

    30

Everything posted by vfbb

  1. v4.0.0 Skia library version has been updated from Milestone 98 to 107; [API] Added support for iOS Simulator ARM 64-bit to RAD Studio 11.2 Alexandria or newer. [API] Added TBitmap.CreateFromSkImage; [Framework] Added LinesCount and DidExceedMaxLines properties to TSkLabel; [Framework] Added new splashscreen to our main demo; [Samples] Added ISkParagraph.Visit method; (#136) [API] Rewritted TSkAnimatedImage and TSkAnimatedPaintBox, adding features to have full control over the animation; (#104) [Framework] Some of them are: Start and Stop methods, and AutoReverse, CurrentTime, Delay, Duration, Enabled, Inverse, Loop, Pause, Progress, Running, Speed, StartFromCurrent, StartProgress and StopProgress properties. All these properties and methods are in the Animation property of the TSkAnimatedImage and TSkAnimatedPaintBox. Improved automatic tests; [Tests] Fixed issue in edit controls with emoji or Chinese char; (#159) [Render] Fixed custom fonts on Android deployed to assets\internals that was not automatically loaded; (#153) [Render] Fixed webinar demo splashscreen; [Samples] Fixed exception loading images from stream or bytes; (#111) [Framework] Fixed TSkAnimatedImage exceeding bounds in some WrapMode [Framework] Fixed TBitmap.SkiaDraw issues in VCL; [Framework] Fixed TBitmap.ToSkImage AV in VCL; [Framework] Fixed flicker problem in TSkAnimatedImage in VCL; [Framework] Fixed text print; (RSP-16301) [Render] Fixed TSkAnimatedImage with 90° rotation that fails to play; [Framework] Fixed high DPI issues of TSkLabel in VCL; [Framework] Fixed high DPI issues in VCL demo; [Samples] Fixed SkRegion.IsEqual; [API] Fixed link with runtime packages; (#163) [Setup] Fixed big GIF issue; (#118) [API] Fixed wrong pixel format on Android in Delphi 10.3 Rio; [Render] Minor improvements and fixes. Skia version: 107.0.0 Compatibility break We are in continuous development, so some updates will bring compatibility breaks. So, pay attention to version numbers, we use semantic versions (for major versions there is some compatibility break). See some breaking changes in this version: No longer use TSkAnimatedImage.Enabled to start or stop an animation. Now use TSkAnimatedImage.Animation.Enabled. The class TSkTypefaceManager is deprecated in favor to TSkDefaultProviders; Several changes in API (Skia.pas); Supported platforms RAD Studio 11 Alexandria: All platforms RAD Studio 10.3 Rio or newer: Windows and Android RAD Studio XE7 or newer: Windows Github: github.com/skia4delphi/skia4delphi Website: skia4delphi.org
  2. vfbb

    ANN: Skia4Delphi v4.0.0

    v4.1.0 Added new parameters to SkCanvas.SaveLayer; API Added functions ComputeFastBounds and CanComputeFastBounds to SkImageFilter; API Added the properties ApproximateOpCount and ApproximateBytesUsed to SkPicture; API Added ShaderButton demo in VCL & FMX (presented at the Embarcadero Brazil Conference 2022); Samples Added virtual methods to TSkLabel; #182 Controls Added support for beta versions of RAD Studio; Setup Improved codecs load; Render Fixed support for iOS Simulator ARM64; #186 Library Fixed invalid float point operation in texts; Render Fixed trimming issue in TTextLayout; #192 Render Fixed Skia's codecs color type on mobile with Skia's render disabled; #197 Render Fixed ISkPath.IsRect results; API Fixed read of Metal view; Render Fixed cursor in TSkLabel of VCL; Controls Fixed text attributes; Render Fixed controls inside TSkCustomAnimatedControl in VCL; Controls Fixed TextLayout before 10.2 Tokyo; Render Fixed iOS certificate issues in main demo; Samples Fixed NavigationBar color on Android12+ in main demo; Samples Fixed and improved unit tests; Tests Minor improvements. Skia version: 107.1.0 New ShaderButton demo (VCL & FMX) ShaderButton.MP4
  3. vfbb

    Upload Google Play android FMX app problem

    You should edit your AndroidManifest.template.xml (You can found it template in your dproj folder after the first compilation to android platform), and not the final AndroidManifest in deploy path.
  4. vfbb

    Upload Google Play android FMX app problem

    Open your Android manifest template, and inside the activity tag, put the line: android:exported="true"
  5. vfbb

    No support for RTL languages in TListView ?

    Not! This part is exemplifying the direct use of the API. It's exactly like @Sherlock said, just replace the default FMX renderer with Skia's renderer ("GlobalUseSkia := True;" in your dpr). But there are a few more notes in the RightToLeft section in readme, which I've printed here:
  6. vfbb

    No support for RTL languages in TListView ?

    FMX does not natively support RTL. However, it is possible to use third-party libraries that enable RTL in FMX. Skia4Delphi is one of them: https://github.com/skia4delphi/skia4delphi#right-to-left
  7. When I said similarity of images, I meant similarity of pixels. It can check if the image is identical (similarity = 1) or if it is very close (similarity >= 0.99 for example). We use this because it is normal for some drawings to vary a few pixels from platform to platform or from backend render to backend render. For example, text on Windows is slightly different from text on Android, even though both have the same font loaded. So in the unit tests we set up some tolerable similarity for each type of drawing.
  8. If you just want to check if 2 images are identical or similar, I have an optimal solution: The Skia4Delphi unit test has an independent unit of image hashing (or similarity hashing). https://github.com/skia4delphi/skia4delphi/blob/main/Tests/Source/Skia.Tests.Foundation.ImageHash.pas Basically, this class allows you to: - Compare 2 images and return the similarity between them (0..1) - Generate a hash of the image - Compare an image with a previously generated hash and return the similarity (0..1) Note: It may seem strange but the hash it generates is a hash itself for similarity, that is, if you change part of the image, only part of the hash will be changed. Internally it implements 3 known similarity algorithms (like perceptual hash) and one of our own. The union of the 4 algorithms is to increase the final accuracy. Logically there is a margin of error, but the accuracy is excellent. You can put for example a check to see if the hash similarity is >= 0.99 to decide if they are equal. In the class, the input parameters of the images are of type ISkImage, which can be created in two different ways: - TSkImage.MakeFromEncoded(Bytes) - Bitmap.ToSkImage; Note: Add the units Skia and Skia.Vcl (or Skia.FMX), to use the example above.
  9. vfbb

    Project Magician blues

    @Uwe Raabe I also wanted to suggest adding a flag to remove the jars. If I remove the android jars from a dproj, I can use the same dproj in any version of Delphi (the IDE will set the default jars when open it). But if I don't remove it, I have to do a 'Revert To Defaults' when I open the project (and an amateur programmer doesn't even know this, will compile and see an error and give up). The solution would be: either add a flag to remove them or check if the list of jars is the defaults of some version of RAD Studio and if it will remove it automatically.
  10. vfbb

    Converting C++ API Post Request into Delphi Code

    You can try using Refit, which is a library to consume apis rest in a simple way, without manipulating strings, json, or http components. First you would create a unit for your api: unit CheckBook; interface uses iPub.Rtl.Refit; // Just download and add it to your project: https://github.com/viniciusfbb/ipub-refit type TNewPayment = record Recipient: string; Name: string; Amount: Double; Number: string; Description: string; end; [BaseUrl('https://sandbox.checkbook.io/v3')] ICheckBookApi = interface(IipRestApi) ['{97789B20-5C26-4359-AC41-D2042C4FAEC7}'] [Post('/check/digital')] [Headers('Authorization', '{AuthToken}')] function CreateDigitalPayment(const ABody: TNewPayment): string; function GetAuthToken: string; procedure SetAuthToken(const AValue: string); property AuthToken: string read GetAuthToken write SetAuthToken; end; var FCheckBookApi: ICheckBookApi; implementation initialization FCheckBookApi := GRestService.&For<ICheckBookApi>; end. Then you would consume it in your forms as follows: uses CheckBook; procedure TForm1.Button1Click(Sender: TObject); var LNewPayment: TNewPayment; begin LNewPayment.Recipient := 'testing@checkbook.io'; LNewPayment.Name := 'Widgets Inc.'; LNewPayment.Amount := 5; LNewPayment.Number := ''; LNewPayment.Description := 'Test Payment'; FCheckBookApi.AuthToken := 'xxxxxxxxx:xxxxxxxx'; ShowMessage(FCheckBookApi.CreateDigitalPayment(LNewPayment)); end;
  11. vfbb

    Draw a path with winding fill mode?

    He needs to draw paths in Winding mode but doesn't want to change the FMX source. This is one of the alternatives, but there are other possibilities.
  12. vfbb

    Draw a path with winding fill mode?

    @XylemFlow You can use the Skia4Delphi for that. I made a small example of how to do this: unit Unit1; interface uses System.SysUtils, System.Types, System.UITypes, System.Classes, System.Variants, FMX.Types, FMX.Controls, FMX.Forms, FMX.Graphics, FMX.Dialogs; type TForm1 = class(TForm) procedure FormPaint(Sender: TObject; Canvas: TCanvas; const ARect: TRectF); private { Private declarations } public { Public declarations } end; var Form1: TForm1; implementation {$R *.fmx} uses {$IFDEF SKIA} Skia, Skia.FMX, Skia.FMX.Graphics, {$ENDIF} System.Math; {$IFDEF SKIA} procedure DrawPath(const ACanvas: ISkCanvas; const APathData: TPathData; const AFillType: TSkPathFillType; const AFill: TBrush; const AStroke: TStrokeBrush); var LPaint: ISkPaint; LPath: ISkPath; LPathBuilder: ISkPathBuilder; begin LPathBuilder := TSkPathBuilder.Create(AFillType); LPathBuilder.AddPath(APathData.ToSkPath); LPath := LPathBuilder.Detach; if (AFill <> nil) and (AFill.Kind = TBrushKind.Solid) then begin LPaint := TSkPaint.Create; LPaint.AntiAlias := True; LPaint.Color := AFill.Color; ACanvas.DrawPath(LPath, LPaint); end; if (AStroke <> nil) and (AStroke.Kind = TBrushKind.Solid) then begin LPaint := TSkPaint.Create(TSkPaintStyle.Stroke); LPaint.AntiAlias := True; LPaint.Color := AStroke.Color; LPaint.StrokeWidth := AStroke.Thickness; ACanvas.DrawPath(LPath, LPaint); end; end; {$ENDIF} procedure TForm1.FormPaint(Sender: TObject; Canvas: TCanvas; const ARect: TRectF); function CircleRect(const ACenterX, ACenterY, ARadius: Single): TRectF; begin Result := TRectF.Create(ACenterX - ARadius, ACenterY - ARadius, ACenterX + ARadius, ACenterY + ARadius); end; var LBitmap: TBitmap; LPathData: TPathData; LRadius: Single; begin LRadius := Min(ARect.Width, ARect.Height) / 4; LPathData := TPathData.Create; LPathData.AddEllipse(CircleRect(ARect.CenterPoint.X - LRadius / 2, ARect.CenterPoint.Y - LRadius / 2, LRadius)); LPathData.AddEllipse(CircleRect(ARect.CenterPoint.X - LRadius / 2, ARect.CenterPoint.Y + LRadius / 2, LRadius)); LPathData.AddEllipse(CircleRect(ARect.CenterPoint.X + LRadius / 2, ARect.CenterPoint.Y - LRadius / 2, LRadius)); LPathData.AddEllipse(CircleRect(ARect.CenterPoint.X + LRadius / 2, ARect.CenterPoint.Y + LRadius / 2, LRadius)); Canvas.Fill.Kind := TBrushKind.Solid; Canvas.Fill.Color := TAlphaColors.Cadetblue; Canvas.Stroke.Kind := TBrushKind.Solid; Canvas.Stroke.Color := TAlphaColors.Chocolate; Canvas.Stroke.Thickness := 8; {$IFDEF SKIA} if Canvas is TSkCanvasCustom then begin DrawPath(TSkCanvasCustom(Canvas).Canvas, LPathData, TSkPathFillType.Winding, Canvas.Fill, Canvas.Stroke); end else begin // Fallback if you remove the "GlobalUseSkia := True;" from .dpr LBitmap := TBitmap.Create(Round(ARect.Width), Round(ARect.Height)); try LBitmap.SkiaDraw( procedure(const ACanvas: ISkCanvas) begin DrawPath(TSkCanvasCustom(Canvas).Canvas, LPathData, TSkPathFillType.Winding, Canvas.Fill, Canvas.Stroke); end); Canvas.DrawBitmap(LBitmap, LBitmap.BoundsF, ARect, 1); finally LBitmap.Free; end; end; {$ELSE} Canvas.FillPath(LPathData, 1); Canvas.DrawPath(LPathData, 1); {$ENDIF} end; end. The result with FMX pure: The result after enable Skia in the project: The project is attached. WindingPath.7z
  13. vfbb

    ANN: Skia4Delphi 4.0.1 compilation error

    @David_Lyon We still don't have an ideal renderer, the complete and correct job would be to replace 25% of the FMX, that is, the entire rendering: TCanvas (of screen and bitmaps), TContext (rendering of 3D forms and shaders) TTextLayout, Codecs, Shaders code (Filters and Effects), Printers, Backends graphic libraries (GLES, Metal, DirectX, ...), Caching systems, and others; Making implementations that use Skia, because Skia is a layer that adds new features, quality, reliability and important optimizations. Much of the work has already been done and works perfectly, and is already faster overall than the default system (see the Benchmark/FmxFPS project in your Skia4Delphi folder). But there are still parts that need to be improved, for example, the performance of bitmaps and effects. About the quality, we did something that FMX should have done: we considered the already existing property Form.Quality to define the quality of the drawings, which can be HighPerformance, SystemDefault or HighQuality. Anti-alias is only disabled when Form.Quality = HighPerformance, which should be your case. Over the past few months we have focused on full API stability, adding features and rendering reliability. It is likely that the performance is in the next targets but, as I said, in the current implementation there are already some gains in the main operations, mainly in the texts, and only some types of applications or hardware show worsening. Note: do not use VM or Debug mode to run the benchmark and I advise leaving Form.Quality = SystemDefault. Furthermore, Skia4Delphi's renderer is optional, that is, you can disable it and use only the library controls for example. In this case, just remove the "GlobalUseSkia := True;" make your .dpr.
  14. vfbb

    ANN: Skia4Delphi 4.0.1 compilation error

    Hi David! What is the exact version you are using? It looks like 11.2, but here on 11.2 Enterprise it works fine. Does this occur on a blank project? Have you tried deleting the output folder of the project? (maybe there is conflict with old dcu)
  15. vfbb

    ANN: Skia4Delphi v4.0.0

    v4.0.1 Added option to "Enable Skia" in dll projects; [Plugin] Fixed AV with GPU canvas; [Render] Fixed exceptions with OpenGLES backend on Android; [Render] Fixed issue with creating bitmap cache (texture); [Render] Fixed 3D controls (TViewPort3D) rendering with OpenGLES backend; [Render] Fixed wrong draw of text with attributes in TTextLayout; [Render] Minor improvements. Skia version: 107.0.0
  16. vfbb

    How can i add a custom font to a windows fmx application

    You should use the font family name (which is not necessarily the same as the file name) in family property of controls. One problem you will face is that this property in designtime only lists the fonts registered on your system, so you must install the font on your system (by double clicking on it), and reopen your IDE, so that you can select your font on the Family property. Note: only you will install the font on the system (to be able to select it inside the IDE), your clients will not need it.
  17. vfbb

    How can i add a custom font to a windows fmx application

    @Linuxuser1234 To be clearer, follow the steps: Install Skia4Delphi via GetIt or by downloading the installer from github. Enable the use of Skia in your project: right click on the project > "Enable Skia" Open your project's dpr to enable Skia as your app's renderer and to register the custom font you want: uses System.StartUpCopy, FMX.Forms, Skia, // << Skia.FMX, // << Unit1 in 'Unit1.pas' {Form1}; {$R *.res} begin GlobalUseSkia := True; // << TSkTypefaceManager.RegisterTypeface('C:\Boltgui\Popups\Font\DSEG14ClassicMini-Bold.ttf'); // << Application.Initialize; ...
  18. vfbb

    How can i add a custom font to a windows fmx application

    Another option that works in XE7+ and cross-platform is use the Skia4delphi as your app render. Then you only need to add the follow code in the app initialization: initialization TSkTypefaceManager.RegisterTypeface('Material Design Icons Desktop.ttf');
  19. You can try with refit unit https://github.com/viniciusfbb/ipub-refit The implementation could be something like this: unit MerchantApi; interface uses iPub.Rtl.Refit; // https://github.com/viniciusfbb/ipub-refit type TCountry = (MG); TCurrency = (MGA); TPaymentSubscriber = record Country: TCountry; Currency: TCurrency; Msisdn: Cardinal; end; TPaymentTransaction = record Amount: Integer; Country: TCountry; Currency: TCurrency; Id: string; end; TPaymentRequest = record Reference: string; Subscriber: TPaymentSubscriber; Transaction: TPaymentTransaction; end; [BaseUrl('https://API_server_host/merchant/v1')] IMerchantApi = interface(IipRestApi) ['{1D10C463-1567-4DE0-88F2-099CC0442E43}'] [Post('/payments')] [Headers('Authorization', 'Bearer {AuthToken}')] [Headers('X-Country', '{XCountry}')] [Headers('X-Currency', '{XCurrency}')] function Payments(AXCountry: TCountry; AXCurrency: TCurrency; const ABody: TPaymentRequest): string; function GetAuthToken: string; procedure SetAuthToken(const AValue: string); property AuthToken: string read GetAuthToken write SetAuthToken; end; var FMerchantApi: IMerchantApi; implementation initialization FMerchantApi := GRestService.&For<IMerchantApi>; end. And your code could be this: uses MerchantApi; procedure TForm1.FormCreate(Sender: TObject); var LPaymentRequest: TPaymentRequest; begin LPaymentRequest.Reference := 'Testing API'; LPaymentRequest.Subscriber.Country := TCountry.MG; LPaymentRequest.Subscriber.Currency := TCurrency.MGA; LPaymentRequest.Subscriber.Msisdn := 331170348; LPaymentRequest.Transaction.Amount := 1000; LPaymentRequest.Transaction.Country := TCountry.MG; LPaymentRequest.Transaction.Currency := TCurrency.MGA; LPaymentRequest.Transaction.Id := 'FE9833FE-D5A3-4450-9786-90735F75EBFB'; FMerchantApi.AuthToken := 'koeQidreesddfzsbxOXKjccccccc'; ShowMessage(FMerchantApi.Payments(TCountry.MG, TCurrency.MGA, LPaymentRequest)); end;
  20. Yes! See a very simple sample: uses System.Net.HttpClient, System.Net.Mime, Skia, Skia.FMX {or Skia.Vcl}; function SendBitmap(const AUrl: string; ABitmap: TBitmap): string; var LRequest: THTTPClient; LFormData: TMultipartFormData; LResponse: TStringStream; begin LRequest := THTTPClient.Create; LFormData := TMultipartFormData.Create; LResponse := TStringStream.Create; try LFormData.AddBytes('img', ABitmap.ToSkImage.EncodeToStream(LImageStream, TSkEncodedImageFormat.WEBP, 80)); LRequest.Post(AUrl, LFormData, LResponse); Result := LResponse.DataString; finally LFormData.Free; LResponse.Free; LRequest.Free; end; end; This is a simple example for you to understand how it works. In practice I use something different. On the client (API consumer), I declare the whole API in a single unit using the Refit library. This removes a lot of complexity throughout the project, as it already magically serializes records and classes, query parameters, headers automatically. The example above using Refit would look like this: This is the unit of your api for the client-side (consumer): unit MyApiConsumer; interface uses System.SysUtils, iPub.Rtl.Refit; // https://github.com/viniciusfbb/ipub-refit type [BaseUrl('http://localhost/api/v1')] IMyAPI = interface(IipRestApi) ['{1D10C463-1567-4DE0-88F2-099CC0442E43}'] [Post('/image-upload')] [ContentType(TBodyKind.MultipartFormData)] function TryImageUpload(const [Body] AImg: TBytes; out AResponse: string): Boolean; end; var FMyApi: IMyAPI; implementation initialization FMyApi := GRestService.&For<IMyAPI>; end. And in your code: uses MyApiConsumer, Skia, Skia.FMX {or Skia.Vcl}; function SendBitmap(ABitmap: TBitmap): string; begin if not FMyApi.TryImageUpload(ABitmap.ToSkImage.EncodeToStream(LImageStream, TSkEncodedImageFormat.WEBP, 80), Result) then Result := 'Failed!'; end;
  21. Don't use json. I usually send via MultipartFormData, encoded in WebP with 80% quality, as it is practically identical to the original. See attached the original png image of 2292 KB and the WebP with 80% quality resulting in 61 KB. photo.webp
  22. Goal: I have configured my app to be opened by some links in iOS, like myapp://lala (using custom scheme), or https://myapp.com/c/lala using universal links, and is already opening my app, but i need to know which url that opened my app. (There is even a tutorial in FMX Express) Problem: I'm trying to handle incoming url from my ios app unsuccessfully. On iOS this should be done by capturing event TApplicationEvent.OpenURL like: procedure TipUrlHandler.ApplicationEventMessageHandler(const ASender: TObject; const AMessage: TMessage); begin case TApplicationEventData(TApplicationEventMessage(AMessage).Value).Event of TApplicationEvent.OpenUrl: HandleUrl(TiOSOpenApplicationContext(TApplicationEventData(TApplicationEventMessage(AMessage).Value).Context).URL); else end; end; Mas o TApplicationEvent.OpenUrl nunca é chamado. So I checked the class TApplicationDelegate in the unit FMX.Platform.iOS.pas in which the TApplicationDelegate.applicationOpenURLWithOptions function should be called every time the app is opened by a url as Apple documents: https://developer.apple.com/documentation/uikit/uiapplicationdelegate/1623112-application?language=objc class function TApplicationDelegate.applicationOpenURLWithOptions(self: id; _cmd: SEL; application: PUIApplication; url: Pointer; options: PNSDictionary): Boolean; So I went to check if the applicationOpenURLWithOptions method is being added correctly in TApplicationDelegate.CreateDelegateMetaClass: class procedure TApplicationDelegate.CreateDelegateMetaClass; begin ... // Opening a URL-Specified Resource if TOSVersion.Major >= 9 then class_addMethod(DelegateClass, sel_getUid('application:openURL:options:'), @applicationOpenURLWithOptions, 'B@:@@@@') else ... end; And then I was able to prove it wrong! The number of arguments declared is wrong, as the correct one should be B@:@@@ Then I made the modification to FMX.Platform.iOS.pas, being as follows: class procedure TApplicationDelegate.CreateDelegateMetaClass; begin ... // Opening a URL-Specified Resource if TOSVersion.Major >= 9 then class_addMethod(DelegateClass, sel_getUid('application:openURL:options:'), @applicationOpenURLWithOptions, 'B@:@@@') else ... end; But the TApplicationDelegate.applicationOpenURLWithOptions function is not yet called. What is wrong? @EDIT Sorry! It is working for custom schemes like "myapp://lala" (with or without the correction in FMX.Platform.iOS.pas) but it is not working for universal links like https://myapp.com/c/lalala. Although I have already configured the universal link correctly and when I click on this universal link, the iOS open my app, but the url can't be handle with TApplicationEvent.OpenUrl, but I discovered that the handling of incoming url of a universal link is different: Handling Universal Links
  23. vfbb

    svg

    Also Skia4Delphi (FMX & VCL). If it's just VCL, SVGIconImageList is the one that has better integration with Delphi controls because it has a TSVGIconImageCollection and TSVGIconVirtualImageList.
  24. vfbb

    Printing from Android Device

    I've never tried to print anything on Android, but on iOS, when sharing a PDF, the "Print" option appears in the system menu. If this happens on Android, it would be a very simple solution to implement. To make the PDF just use Skia4delphi, and to share the PDF, it's very simple, I even have a code ready (if you confirm that this solution works, I'll send it to you).
  25. v3.4.0 Added StrokeColor property to TSkLabel; Added LetterSpacing property to TSkLabel; Added automatically Skia to uses when use controls in form; Added EncodedImageFormat property and MakeFromStream to SkCodec; Added MakeRawShader to SkImage; Added MakeImage to SkRuntimeEffects; Exposed DirectContext in TGrCanvasCustom class to run code on the GPU more easily; Fixed BackgroundColor property of TSkLabel; Fixed issue loading bitmaps from stream when using Skia in Vcl project; Fixed build script with python3 as default; Minor improvements and fixes. New StrokeColor property of TSkLabel Github: github.com/skia4delphi/skia4delphi Website: skia4delphi.org
×