<commit_before>Unit RichTextLayoutUnit;

{$mode objfpc}{$H+}

// Dynamically created layout class.
// Represents a laid out rich text document

Interface

Uses
  Classes,
  CanvasFontManager,
  RichTextDocumentUnit,
  RichTextStyleUnit,
  fpg_imagelist,
  contnrs;

Type

  TLayoutLine = class(TObject)
  public
    Text: PChar;
    Length: longint;
    Height: longint;
    Width: longint;
    MaxDescender: longint;
    MaxTextHeight: longint; // maximum height of text, doesn't include images
    LinkIndex: longint; // link index at start of line, if any
    Style: TTextDrawStyle;
    Wrapped: boolean;
  end;


  TLayoutLineList = class(TObjectList)
  protected
    function GetItem(Index: Integer): TLayoutLine; reintroduce;
    procedure SetItem(Index: Integer; const AValue: TLayoutLine); reintroduce;
  public
    function Add(AObject: TLayoutLine): Integer; reintroduce;
    function Remove(AObject: TLayoutLine): Integer; reintroduce;
    function IndexOf(AObject: TLayoutLine): Integer; reintroduce;
    function First: TLayoutLine; reintroduce;
    Function Last: TLayoutLine; reintroduce;
    property Items[Index: Integer]: TLayoutLine read GetItem write SetItem; default;
  end;


  TTextPosition = (
        tpAboveTextArea,
        tpAboveText,
        tpWithinText,
        tpBelowText,
        tpBelowTextArea
      );


  // forward declaration
  TRichTextLayout = class;


//  TLinkEvent = procedure( Sender: TRichTextLayout; Link: string ) of object;


  TRichTextLayout = class(TObject)
  Protected
    FFontManager: TCanvasFontManager;
    FText: PChar;
    FImages: TfpgImageList;
    FLayoutWidth: longint; // The target width for the layout. Used for centreing/right align
    FWidth: longint;       // The actual width of the text. May be wider due to unaligned
                           // parts or bitmaps or width so small individual characters don't fit.
    FHeight: longint;
    FLinks: TStringList;
    FHorizontalImageScale: double;
    FVerticalImageScale: double;
  public
    FLines: TLayoutLineList;
    FNumLines: longint;
    FRichTextSettings: TRichTextSettings;
    // Drawing functions
    Procedure PerformStyleTag( Const Tag: TTag;
                               Var Style: TTextDrawStyle;
                               const X: longint );
    function GetElementWidth( Element: TTextElement ): longint;
    // Queries
    Function GetStartX( Style: TTextDrawStyle; Line: TLayoutLine ): longint;
    Procedure GetXFromOffset( const Offset: longint;
                              const LineIndex: longint;
                              Var X: longint );
    Procedure GetOffsetFromX( const XToFind: longint;
                              const LineIndex: longint;
                              Var Offset: longint;
                              Var Link: string );
    function FindPoint( XToFind, YToFind: longint;
                        Var LineIndex: longint;
                        Var Offset: longint;
                        Var Link: string ): TTextPosition;
    function GetLineFromCharIndex( Index: longint ): longint;
    function GetOffsetFromCharIndex( Index: longint;
                                     Line: longint ): longint;
    function GetLinePosition( Line: longint ): longint;
    function GetLineFromPosition( YToFind: longint;
                                  Var LineIndex: longint;
                                  Var Remainder: longint ): TTextPosition;
    // Layout functions
    Procedure   AddLineStart(var Line: TLayoutLine);
    Procedure   CheckFontHeights(var Line: TLayoutLine);
    Procedure   Layout;
    function    IsValidBitmapIndex( Index: longint ): boolean;
    // property handlers
    Function    GetCharIndex( P: PChar ): longint;
    Function    GetTextEnd: longint;
  public
    constructor Create(Text: PChar; Images: TfpgImageList; RichTextSettings: TRichTextSettings; FontManager: TCanvasFontManager; AWidth: longint);
    destructor  Destroy; Override;
    function    LinkFromIndex( const CharIndexToFind: longint): string;
    property    TextEnd: longint read GetTextEnd;
    property    Images: TfpgImageList read FImages;
    property    Width: longint read FWidth;
    property    Height: longint read FHeight;
    property    HorizontalImageScale: double read FHorizontalImageScale;
    property    VerticalImageScale: double read FVerticalImageScale;
  end;


implementation

uses
  SysUtils,
  ACLStringUtility,
  nvUtilities,
  fpg_main;


{ TLayoutLineList }

function TLayoutLineList.GetItem(Index: Integer): TLayoutLine;
begin
  inherited GetItem(Index);
end;

procedure TLayoutLineList.SetItem(Index: Integer; const AValue: TLayoutLine);
begin
  inherited SetItem(Index, AValue);
end;

function TLayoutLineList.Add(AObject: TLayoutLine): Integer;<commit_msg>richview: correctly typecast result in TLayoutLineList.GetItem()<commit_after>Unit RichTextLayoutUnit;

{$mode objfpc}{$H+}

// Dynamically created layout class.
// Represents a laid out rich text document

Interface

Uses
  Classes,
  CanvasFontManager,
  RichTextDocumentUnit,
  RichTextStyleUnit,
  fpg_imagelist,
  contnrs;

Type

  TLayoutLine = class(TObject)
  public
    Text: PChar;
    Length: longint;
    Height: longint;
    Width: longint;
    MaxDescender: longint;
    MaxTextHeight: longint; // maximum height of text, doesn't include images
    LinkIndex: longint; // link index at start of line, if any
    Style: TTextDrawStyle;
    Wrapped: boolean;
  end;


  TLayoutLineList = class(TObjectList)
  protected
    function GetItem(Index: Integer): TLayoutLine; reintroduce;
    procedure SetItem(Index: Integer; const AValue: TLayoutLine); reintroduce;
  public
    function Add(AObject: TLayoutLine): Integer; reintroduce;
    function Remove(AObject: TLayoutLine): Integer; reintroduce;
    function IndexOf(AObject: TLayoutLine): Integer; reintroduce;
    function First: TLayoutLine; reintroduce;
    Function Last: TLayoutLine; reintroduce;
    property Items[Index: Integer]: TLayoutLine read GetItem write SetItem; default;
  end;


  TTextPosition = (
        tpAboveTextArea,
        tpAboveText,
        tpWithinText,
        tpBelowText,
        tpBelowTextArea
      );


  // forward declaration
  TRichTextLayout = class;


//  TLinkEvent = procedure( Sender: TRichTextLayout; Link: string ) of object;


  TRichTextLayout = class(TObject)
  Protected
    FFontManager: TCanvasFontManager;
    FText: PChar;
    FImages: TfpgImageList;
    FLayoutWidth: longint; // The target width for the layout. Used for centreing/right align
    FWidth: longint;       // The actual width of the text. May be wider due to unaligned
                           // parts or bitmaps or width so small individual characters don't fit.
    FHeight: longint;
    FLinks: TStringList;
    FHorizontalImageScale: double;
    FVerticalImageScale: double;
  public
    FLines: TLayoutLineList;
    FNumLines: longint;
    FRichTextSettings: TRichTextSettings;
    // Drawing functions
    Procedure PerformStyleTag( Const Tag: TTag;
                               Var Style: TTextDrawStyle;
                               const X: longint );
    function GetElementWidth( Element: TTextElement ): longint;
    // Queries
    Function GetStartX( Style: TTextDrawStyle; Line: TLayoutLine ): longint;
    Procedure GetXFromOffset( const Offset: longint;
                              const LineIndex: longint;
                              Var X: longint );
    Procedure GetOffsetFromX( const XToFind: longint;
                              const LineIndex: longint;
                              Var Offset: longint;
                              Var Link: string );
    function FindPoint( XToFind, YToFind: longint;
                        Var LineIndex: longint;
                        Var Offset: longint;
                        Var Link: string ): TTextPosition;
    function GetLineFromCharIndex( Index: longint ): longint;
    function GetOffsetFromCharIndex( Index: longint;
                                     Line: longint ): longint;
    function GetLinePosition( Line: longint ): longint;
    function GetLineFromPosition( YToFind: longint;
                                  Var LineIndex: longint;
                                  Var Remainder: longint ): TTextPosition;
    // Layout functions
    Procedure   AddLineStart(var Line: TLayoutLine);
    Procedure   CheckFontHeights(var Line: TLayoutLine);
    Procedure   Layout;
    function    IsValidBitmapIndex( Index: longint ): boolean;
    // property handlers
    Function    GetCharIndex( P: PChar ): longint;
    Function    GetTextEnd: longint;
  public
    constructor Create(Text: PChar; Images: TfpgImageList; RichTextSettings: TRichTextSettings; FontManager: TCanvasFontManager; AWidth: longint);
    destructor  Destroy; Override;
    function    LinkFromIndex( const CharIndexToFind: longint): string;
    property    TextEnd: longint read GetTextEnd;
    property    Images: TfpgImageList read FImages;
    property    Width: longint read FWidth;
    property    Height: longint read FHeight;
    property    HorizontalImageScale: double read FHorizontalImageScale;
    property    VerticalImageScale: double read FVerticalImageScale;
  end;


implementation

uses
  SysUtils,
  ACLStringUtility,
  nvUtilities,
  fpg_main;


{ TLayoutLineList }

function TLayoutLineList.GetItem(Index: Integer): TLayoutLine;
begin
  result := TLayoutLine( inherited GetItem(Index));
end;

procedure TLayoutLineList.SetItem(Index: Integer; const AValue: TLayoutLine);
begin
  inherited SetItem(Index, AValue);
end;

function TLayoutLineList.Add(AObject: TLayoutLine): Integer;
{'fraction_non_alphanumeric': 0.06890111030403652, 'fraction_numerical': 0.0, 'mean_word_length': 2.7589703588143526, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 14, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '7583511', 'n_tokens_mistral': 2750, 'n_tokens_neox': 2651, 'n_words': 790}