Skip to content
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: skia4delphi/skia4delphi
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: main
Choose a base ref
...
head repository: skia4delphi/skia4delphi
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: CreateAsInterface
Choose a head ref
  • 6 commits
  • 15 files changed
  • 2 contributors

Commits on Apr 3, 2025

  1. proposal - see readme.md

    # Skia4Delphi `AsInterface` Proposal & Demo
    
    Most of the Skia API is exposed as interfaces. This takes advantage of reference counting, which is nice to have. Usually, the class has limited public methods and most functionality is exposed through the interface.
    
    **Example:**
    
    ```Delphi
    type
       { ISkPaint }
    
      ISkPaint = interface(ISkObject)
        ['{C95825F8-0D51-4BCE-8945-84AFE6264213}']
        function GetAlpha: Byte;
        function GetAlphaF: Single;
    
        { ... 50 other PUBLIC members ...}
    
        property StrokeWidth: Single read GetStrokeWidth write SetStrokeWidth;
        property Style: TSkPaintStyle read GetStyle write SetStyle;
      end;
    
      { TSkPaint }
    
      TSkPaint = class(TSkObject, ISkPaint)
      strict private
        function GetAlpha: Byte;
        function GetAlphaF: Single;
    
        { ... 34 other STRICT PRIVATE memebers ... }
    
        procedure SetStrokeWidth(const AValue: Single);
        procedure SetStyle(const AValue: TSkPaintStyle);
      public
        constructor Create; overload;
        constructor Create(const APaint: ISkPaint); overload;
        constructor Create(const AStyle: TSkPaintStyle); overload;
      end;
      ```
    
    This is fine for *traditional* variable declarations:
    
    ```Delphi
    var
      paint: ISkPaint;
    begin
      paint := TSkPaint.Create;
      paint.Color := TAlphaColors.Darkorange;
    end;
    ```
    
    Unfortunately, it is *incompatible* with **type inferance**:
    
    ```Delphi
    begin
      var inferred := TSkPaint.Create;
      inferred.Color := TAlphaColors.Darkorange; // E2003 Undeclared identifier: 'Color'
    end;
    ```
    
    Forces the more verbose form of inline variable declaration:
    
    ```Delphi
    begin
      var explicit: ISkPaint := TSkPaint.Create();
      explicit.Color := TAlphaColors.Darkorange;
    end;
    ```
    
    The proposed `CreateAsInterace` methods fix this:
    
    ```Delphi
    begin
      var better := TSkPaint.Create();
      better.Color := TAlphaColors.Darkorange;
    end;
    ```
    
    Simply duplicate the existing constructors:
    
    ```Delphi
    public
      constructor Create; overload;
      constructor Create(const APaint: ISkPaint); overload;
      constructor Create(const AStyle: TSkPaintStyle); overload;
    end;
    ```
    
    Making them a `class function` named `CreateAsInterface` with the same arguements, and returning the `interface`:
    
    ```Delphi
    public
      class function CreateAsInterface: ISkPaint; overload;
      class function CreateAsInterface(const APaint: ISkPaint): ISkPaint; overload;
      class function CreateAsInterface(const AStyle: TSkPaintStyle): ISkPaint; overload;
    end;
    ```
    
    Any name could be used (`Init`, `AsInterface`, `George`, etc.), but this one makes them very visible in class completion to aid in discovery.
    
    The implementation just calls the existing constructors, but since the Result is explicitly the Interface, this works as expected:
    
    ```Delphi
    implementation
    
    { TSkPaint }
    
    class function TSkPaint.CreateAsInterface: ISkPaint;
    begin
      Result := TSkPaint.Create();
    end;
    
    class function TSkPaint.CreateAsInterface(const APaint: ISkPaint): ISkPaint;
    begin
      Result := TSkPaint.Create(APaint);
    end;
    
    class function TSkPaint.CreateAsInterface(const AStyle: TSkPaintStyle): ISkPaint;
    begin
      Result := TSkPaint.Create(AStyle);
    end;
    ```
    
    Type inferance is as preferable. Beyond less typing it makes code more maintainable (type only needs to be changed in one place) and reduces errors resulting from mismatched types and constructors. The easier it is to take advantage of this feature in Delphi the better.
    jimmckeeth committed Apr 3, 2025
    Configuration menu
    Copy the full SHA
    dc611f0 View commit details
    Browse the repository at this point in the history
  2. Configuration menu
    Copy the full SHA
    3c42803 View commit details
    Browse the repository at this point in the history
  3. proposal - see CreateAsInterface sample

    C:\Users\jim\Documents\GitHub\skia4delphi\Samples\CreateAsInterface
    jimmckeeth committed Apr 3, 2025
    Configuration menu
    Copy the full SHA
    af9123b View commit details
    Browse the repository at this point in the history

Commits on Apr 8, 2025

  1. Configuration menu
    Copy the full SHA
    83f3e96 View commit details
    Browse the repository at this point in the history

Commits on Apr 9, 2025

  1. updated based on feedback

    and implemented on other classes
    
    * TSkColorFilter - For color transformations
    * TSkFont - Font rendering and text metrics handling
    * TSkPaint - Graphics styling configuration including colors, strokes, and effects
    * TSkParagraphBuilder - A builder class for creating formatted text paragraphs with advanced text layout features like styles, fonts, and text decorations
    * TSkParagraphStyle - Styling configuration for paragraph layouts
    * TSkPath - Vector path definition and manipulation
    * TSkPathBuilder - Used for building paths incrementally
    * TSkPathMeasure - For measuring and extracting information about paths
    * TSkPictureRecorder - Used for recording drawing commands
    * TSkPixmap - For pixel buffer access
    * TSkRegion - Represents a 2D set of pixels for clipping or hit-testing
    * TSkRoundRect - Used for rounded rectangles
    * TSkRuntimeBlenderBuilder - A builder class for creating custom blend modes at runtime, enabling custom pixel blending operations
    * TSkRuntimeShaderBuilder - A builder class for creating custom shaders at runtime, allowing dynamic generation of graphical effects and patterns
    * TSkShaper - Text shaping engine for complex script rendering
    * TSkString - String handling utilities for Skia
    * TSkStrutStyle - Text layout configuration for line spacing and alignment
    * TSkTextStyle - Text styling configuration for paragraphs
    * TSkUnicode - Unicode text processing and manipulation utilities for international text handling
    jimmckeeth committed Apr 9, 2025
    Configuration menu
    Copy the full SHA
    af209c5 View commit details
    Browse the repository at this point in the history
  2. Configuration menu
    Copy the full SHA
    3f84ae1 View commit details
    Browse the repository at this point in the history
Loading