{********************************************************************}
{                                                                    }
{ written by TMS Software                                            }
{            copyright © 2013                                        }
{            Email : info@tmssoftware.com                            }
{            Web : http://www.tmssoftware.com                        }
{                                                                    }
{ The source code is given as is. The author is not responsible      }
{ for any possible damage done due to the use of this code.          }
{ The complete source code remains property of the author and may    }
{ not be distributed, published, given or sold in any form as such.  }
{ No parts of the source code can be included in any other component }
{ or application without written authorization of the author.        }
{********************************************************************}

unit FMX.TMSMatrixLabel;

interface

{$I TMSDEFS.INC}

uses
  FMX.Types, FMX.Objects, Classes, Types,
  SysUtils, Math, UITypes, UIConsts, FMX.TMSBasecontrol, FMX.Controls, Rtti
  {$IFDEF DELPHIXE5_LVL}
  , FMX.Graphics
  {$ENDIF}
  ;

const
  MAJ_VER = 1; // Major version nr.
  MIN_VER = 0; // Minor version nr.
  REL_VER = 5; // Release nr.
  BLD_VER = 2; // Build nr.

  // version history
  // v1.0.0.0 : first release
  // v1.0.4.2 : Reorganized packages
  // v1.0.5.0 : New : support for update 4
  // v1.0.5.1 : Improved : TMSIOS define
  // v1.0.5.2 : New : support for update 4 hotfix 1

type
  TMatrixLedStyle = (ls9x13, ls14x20, ls19x27);
  TMatrixScrollDirection = (msdRightToLeft, msdLeftToRight);
  TMatrixTextStyle = (tsUpperCase, tsLowerCase, tsAsIs, tsProperCase);
  TVrAlignment = (vaLeftJustify, vaRightJustify, vaCenter);
  TVrOrientation = (voVertical, voHorizontal);

  TLEDPalette = class(TPersistent)
  private
    FLow: TAlphaColor;
    FHigh: TAlphaColor;
    FUpdateCount: Integer;
    FOnChange: TNotifyEvent;
    procedure SetLow(Value: TAlphaColor);
    procedure SetHigh(Value: TAlphaColor);
    function GetColors(Index: Integer): TColor; virtual;
  protected
    procedure Changed;
  public
    constructor Create;
    procedure Assign(Source: TPersistent); override;
    //procedure ToBMP(Bitmap: TBitmap; DarkColor, LightColor: TColor);
    procedure BeginUpdate;
    procedure EndUpdate;
    property OnChange: TNotifyEvent read FOnChange write FOnChange;
    property Colors[Index: Integer]: TColor read GetColors; default;
  published
    property Low: TAlphaColor read FLow write SetLow;
    property High: TAlphaColor read FHigh write SetHigh;
  end;

  [ComponentPlatformsAttribute(TMSPlatforms)]
  TLEDText = class(TTMSFMXBaseShape)
  private
    FText: String;
    FFont: TFont;
    FVertTextAlign: TTextAlign;
    FHorzTextAlign: TTextAlign;
    FWordWrap: Boolean;
    FAutoSize: Boolean;
    FStretch: Boolean;
    FLedsVisible: Boolean;
    FTextStyle: TMatrixTextStyle;
    FAlignment: TVrAlignment;
    FSpacing: Integer;
    FLeds: Integer;
    FLedStyle: TMatrixLedStyle;
    FOrientation: TVrOrientation;
    FPosition: Integer;
    Fledw, fLedh: integer;
    FChars: string;
    FColors: string;
    FCurColor: Char;
    FPalette: TLEDPalette;
    FAutoScroll: Boolean;
    FTimer: TTimer;
    FScrollDirection: TMatrixScrollDirection;
    FMargin: Integer;
    procedure OnPaletteChanged(Sender: TObject);
    procedure OnTimerEvent(Sender: TObject);
    procedure SetText(const Value: String);
    procedure SetFont(const Value: TFont);
    procedure SetHorzTextAlign(const Value: TTextAlign);
    procedure SetVertTextAlign(const Value: TTextAlign);
    procedure SetWordWrap(const Value: Boolean);
    procedure SetAutoSize(const Value: Boolean);
    procedure SetStretch(const Value: Boolean);

    procedure SetAlignment(const Value: TVrAlignment);
    procedure SetLeds(const Value: Integer);
    procedure SetLedStyle(const Value: TMatrixLedStyle);
    procedure SetLedsVisible(const Value: Boolean);
    procedure SetOrientation(const Value: TVrOrientation);
    procedure SetSpacing(const Value: Integer);
    procedure SetTextStyle(const Value: TMatrixTextStyle);
    procedure SetPalette(const Value: TLEDPalette);
    procedure SetAutoScroll(const Value: Boolean);
    function GetTimeInterval: Integer;
    procedure SetTimeInterval(const Value: Integer);
    procedure SetMargin(const Value: Integer);
  protected
    procedure FontChanged(Sender: TObject); virtual;
    procedure Paint; override;
    function GetData: TValue; override;
    procedure SetData(const Value: TValue); override;
    procedure AdjustSize;
    procedure LoadBitmaps; virtual;
    procedure Loaded; override;
    procedure AdjustControlSize; virtual;
    procedure UpdateAlignment;
    procedure Decode(S: string);
    procedure PaintLed(X, Y: Single; Ch: Char; AColor: TAlphaColor);
    procedure PaintLeds;
    procedure DoScrollDone; virtual;
    procedure UpdateControlCanvas; virtual;
    property AutoScroll: Boolean read FAutoScroll write SetAutoScroll default false;
    property TimeInterval: Integer read GetTimeInterval write SetTimeInterval default 500;
    property ScrollDirection: TMatrixScrollDirection read FScrollDirection write FScrollDirection default msdRightToLeft;
  public
    constructor Create(AOwner: TComponent); override;
    destructor Destroy; override;
  published
    property AutoSize: Boolean read FAutoSize write SetAutoSize default false;
    property Fill;
    property Font: TFont read FFont write SetFont;
    property HorzTextAlign: TTextAlign read FHorzTextAlign
      write SetHorzTextAlign;// default vgTextAlignCenter;
    property VertTextAlign: TTextAlign read FVertTextAlign
      write SetVertTextAlign;// default vgTextAlignCenter;
    property Text: String read FText write SetText;
    property Stretch: Boolean read FStretch write SetStretch default false;
    property WordWrap: Boolean read FWordWrap write SetWordWrap default true;

    //property Threaded: Boolean read GetThreaded write SetThreaded;
    property TextStyle: TMatrixTextStyle read FTextStyle write SetTextStyle default tsUpperCase;
    property Orientation: TVrOrientation read FOrientation write SetOrientation default voHorizontal;
    property Leds: Integer read FLeds write SetLeds default 15;
    property Spacing: Integer read FSpacing write SetSpacing default 2;
    property Palette: TLEDPalette read FPalette write SetPalette;
    property LedStyle: TMatrixLedStyle read FLedStyle write SetLedStyle default ls14x20;
    property LedsVisible: Boolean read FLedsVisible write SetLedsVisible default True;
    property Alignment: TVrAlignment read FAlignment write SetAlignment default vaLeftJustify;
    property Margin: Integer read FMargin write SetMargin default 10;
    //property Bevel: TVrBevel read FBevel write SetBevel;
  end;

  [ComponentPlatformsAttribute(TMSPlatforms)]
  TTMSFMXMatrixLabel = class(TTMSFMXBaseControl)
  private
    FAutoScroll: Boolean;
    FTimeInterval: Integer;
    FScrollDirection: TMatrixScrollDirection;
    FText: String;
    procedure SetAutoScroll(const Value: Boolean);
    procedure SetScrollDirection(const Value: TMatrixScrollDirection);
    procedure SetTimeInterval(const Value: Integer);
    procedure SetText(const Value: String);
    function GetVersion: String;
    function GetVersionNr: Integer;
  protected
    function GetInstance: NativeUInt; override;
    function GetStyleObject: TFMXObject; override;
    procedure ApplyProperties(AControl: TFMXObject);
    procedure ApplyStyle; override;
  public
    constructor Create(AOwner: TComponent); override;
    procedure SetBounds(X, Y, AWidth, AHeight: Single); override;
  published
    property Version: String read GetVersion;
    property Text: String read FText write SetText;
    property AutoScroll: Boolean read FAutoScroll write SetAutoScroll default false;
    property TimeInterval: Integer read FTimeInterval write SetTimeInterval default 500;
    property ScrollDirection: TMatrixScrollDirection read FScrollDirection write SetScrollDirection default msdRightToLeft;
  end;

implementation

{$R FMX.TMSMatrixlabel.res}

//------------------------------------------------------------------------------

const
  CharState: array[0..1791] of byte = { all ASCII according to Hewlett Packard HDSP 2470 }
              ($02, $06, $0e, $1e, $0e, $06, $02,     { NUL }
               $04, $00, $04, $08, $11, $11, $0e,     { SOH }
               $1f, $00, $11, $0a, $04, $0a, $11,     { STX }
               $1f, $00, $11, $19, $15, $13, $11,     { ETX }
               $1f, $00, $16, $19, $11, $11, $11,     { EOT }
               $00, $00, $0d, $12, $12, $12, $0d,     { ENQ }
               $1c, $12, $12, $16, $11, $16, $10,     { ACK }
               $06, $08, $04, $0e, $11, $11, $0e,     { BEL }
               $00, $00, $00, $04, $0a, $11, $1f,     { BS }
               $00, $10, $1c, $12, $12, $02, $01,     { HT }
               $0e, $11, $11, $1f, $11, $11, $0e,     { LF }
               $00, $10, $08, $04, $0a, $11, $11,     { VT }
               $00, $00, $09, $09, $09, $0e, $10,     { FF }
               $00, $01, $0e, $1a, $0a, $0a, $0a,     { CR }
               $00, $00, $0f, $12, $12, $12, $0c,     { SO }
               $1f, $08, $04, $02, $04, $08, $1f,     { SI }
               $00, $00, $01, $0e, $14, $04, $04,     { DLE }
               $00, $04, $0e, $15, $15, $0e, $04,     { DC1 }
               $0e, $11, $11, $11, $11, $0a, $1b,     { DC2 }
               $04, $00, $0e, $11, $1f, $11, $11,     { DC3 }
               $04, $00, $0e, $12, $12, $12, $0d,     { DC4 }
               $0a, $00, $0e, $11, $1f, $11, $11,     { NAK }
               $0a, $00, $0e, $12, $12, $12, $0d,     { SYN }
               $0a, $0e, $11, $11, $11, $11, $0e,     { ETB }
               $0a, $00, $0e, $11, $11, $11, $0e,     { CAN }
               $0a, $00, $11, $11, $11, $11, $0e,     { EM }
               $00, $0a, $00, $11, $11, $11, $0e,     { SUB }
               $00, $04, $02, $1f, $02, $04, $00,     { ESC }
               $00, $0f, $08, $08, $08, $18, $08,     { FS }
               $0c, $12, $04, $08, $1e, $00, $00,     { GS }
               $06, $09, $08, $1c, $08, $08, $1f,     { RS }
               $11, $0a, $04, $04, $0e, $04, $04,     { US }
               $00, $00, $00, $00, $00, $00, $00,     { Space }
               $08, $08, $08, $08, $08, $00, $08,     { ! }
               $0a, $0a, $00, $00, $00, $00, $00,     { " }
               $0a, $0a, $1f, $0a, $1f, $0a, $0a,     { # }
               $04, $0f, $14, $0e, $05, $1e, $04,     { $ }
               $18, $19, $02, $04, $08, $13, $03,     { % }
               $08, $14, $14, $08, $15, $12, $0d,     { & }
               $0c, $0c, $04, $08, $00, $00, $00,     { ' }
               $02, $04, $04, $04, $04, $04, $02,     { ( }
               $08, $04, $04, $04, $04, $04, $08,     { ) }
               $00, $0a, $04, $1f, $04, $0a, $00,     { * }
               $00, $04, $04, $1f, $04, $04, $00,     { + }
               $00, $00, $00, $0c, $0c, $04, $08,     { , }
               $00, $00, $00, $1f, $00, $00, $00,     { - }
               $00, $00, $00, $00, $0c, $0c, $00,     { . }
               $00, $01, $02, $04, $08, $10, $00,     { / }
               $0e, $11, $13, $15, $19, $11, $0e,     { 0 }
               $04, $0c, $04, $04, $04, $04, $0e,     { 1 }
               $0e, $11, $01, $06, $08, $10, $1f,     { 2 }
               $0e, $11, $01, $06, $01, $11, $0e,     { 3 }
               $02, $06, $0a, $12, $1f, $02, $02,     { 4 }
               $1f, $10, $1e, $01, $01, $11, $0e,     { 5 }
               $06, $08, $10, $1e, $11, $11, $0e,     { 6 }
               $1f, $01, $02, $04, $08, $08, $08,     { 7 }
               $0e, $11, $11, $0e, $11, $11, $0e,     { 8 }
               $0e, $11, $11, $0f, $01, $02, $0c,     { 9 }
               $00, $0c, $0c, $00, $0c, $0c, $00,     { : }
               $0c, $0c, $00, $0c, $0c, $04, $08,     { ; }
               $01, $02, $04, $08, $04, $02, $01,     { < }
               $00, $00, $1f, $00, $1f, $00, $00,     { = }
               $10, $08, $04, $02, $04, $08, $10,     { > }
               $0e, $11, $01, $02, $04, $00, $04,     { ? }
               $0e, $11, $17, $15, $17, $10, $0e,     { @ }
               $0e, $11, $11, $1f, $11, $11, $11,     { A }
               $1e, $11, $11, $1e, $11, $11, $1e,     { B }
               $0e, $11, $10, $10, $10, $11, $0e,     { C }
               $1e, $11, $11, $11, $11, $11, $1e,     { D }
               $1f, $10, $10, $1e, $10, $10, $1f,     { E }
               $1f, $10, $10, $1e, $10, $10, $10,     { F }
               $0e, $11, $10, $10, $13, $11, $0f,     { G }
               $11, $11, $11, $1f, $11, $11, $11,     { H }
               $0e, $04, $04, $04, $04, $04, $0e,     { I }
               $01, $01, $01, $01, $01, $11, $0e,     { J }
               $11, $12, $14, $18, $14, $12, $11,     { K }
               $10, $10, $10, $10, $10, $10, $1f,     { L }
               $11, $1b, $15, $15, $11, $11, $11,     { M }
               $11, $11, $19, $15, $13, $11, $11,     { N }
               $0e, $11, $11, $11, $11, $11, $0e,     { O }
               $1e, $11, $11, $1e, $10, $10, $10,     { P }
               $0e, $11, $11, $11, $15, $12, $0d,     { Q }
               $1e, $11, $11, $1e, $14, $12, $11,     { R }
               $0e, $11, $10, $0e, $01, $11, $0e,     { S }
               $1f, $04, $04, $04, $04, $04, $04,     { T }
               $11, $11, $11, $11, $11, $11, $0e,     { U }
               $11, $11, $11, $11, $11, $0a, $04,     { V }
               $11, $11, $11, $15, $15, $1b, $11,     { W }
               $11, $11, $0a, $04, $0a, $11, $11,     { X }
               $11, $11, $0a, $04, $04, $04, $04,     { Y }
               $1f, $01, $02, $04, $08, $10, $1f,     { Z }
               $07, $04, $04, $04, $04, $04, $07,     { [ }
               $00, $10, $08, $04, $02, $01, $00,     { \ }
               $1c, $04, $04, $04, $04, $04, $1c,     { ] }
               $04, $0e, $15, $04, $04, $04, $04,     { ^ }
               $00, $00, $00, $00, $00, $00, $1f,     { _ }
               $0c, $0c, $08, $04, $00, $00, $00,     { ` }
               $00, $00, $0e, $12, $12, $12, $0d,     { a }
               $10, $10, $16, $19, $11, $11, $1e,     { b }
               $00, $00, $0e, $10, $10, $11, $0e,     { c }
               $01, $01, $0d, $13, $11, $11, $0f,     { d }
               $00, $00, $0e, $11, $1e, $10, $0e,     { e }
               $04, $0a, $08, $1c, $08, $08, $08,     { f }
               $00, $00, $0f, $11, $0f, $01, $06,     { g }
               $10, $10, $16, $19, $11, $11, $11,     { h }
               $04, $00, $0c, $04, $04, $04, $0e,     { i }
               $02, $00, $06, $02, $02, $12, $0c,     { j }
               $08, $08, $09, $0a, $0c, $0a, $09,     { k }
               $0c, $04, $04, $04, $04, $04, $0e,     { l }
               $00, $00, $0a, $15, $15, $11, $11,     { m }
               $00, $00, $16, $19, $11, $11, $11,     { n }
               $00, $00, $0e, $11, $11, $11, $0e,     { o }
               $00, $00, $1e, $11, $19, $16, $10,     { p }
               $00, $00, $0e, $12, $16, $0a, $03,     { q }
               $00, $00, $0b, $0c, $08, $08, $08,     { r }
               $00, $00, $0e, $10, $0e, $01, $1e,     { s }
               $00, $08, $1c, $08, $08, $0a, $04,     { t }
               $00, $00, $11, $11, $11, $13, $0d,     { u }
               $00, $00, $11, $11, $11, $0a, $04,     { v }
               $00, $00, $11, $11, $15, $15, $0a,     { w }
               $00, $00, $11, $0a, $04, $0a, $11,     { x }
               $00, $00, $11, $0a, $04, $04, $08,     { y }
               $00, $00, $1f, $02, $04, $08, $1f,     { z }
               $02, $04, $04, $08, $04, $04, $02,     (* { *)
               $04, $04, $04, $00, $04, $04, $04,     { | }
               $08, $04, $04, $02, $04, $04, $08,     (* } *)
               $00, $00, $08, $15, $02, $00, $00,     { ~ }
               $0a, $15, $0a, $15, $0a, $15, $0a,     { DEL }
               $0,  $0,  $0,  $0,  $0,  $0,  $0,     { none }
               $0,  $0,  $0,  $0,  $0,  $0,  $0,     { none }
               $0,  $0,  $0,  $0,  $0,  $0,  $0,     { none }
               $0,  $0,  $0,  $0,  $0,  $0,  $0,     { none }
               $0,  $0,  $0,  $0,  $0,  $0,  $0,     { none }
               $0,  $0,  $0,  $0,  $0,  $0,  $0,     { none }
               $0,  $0,  $0,  $0,  $0,  $0,  $0,     { none }
               $0,  $0,  $0,  $0,  $0,  $0,  $0,     { none }
               $0,  $0,  $0,  $0,  $0,  $0,  $0,     { none }
               $0,  $0,  $0,  $0,  $0,  $0,  $0,     { none }
               $06, $0e, $10, $0e, $01, $11, $0e,    { S  caron}
               $0,  $0,  $0,  $0,  $0,  $0,  $0,     { none }
               $0,  $0,  $0,  $0,  $0,  $0,  $0,     { none }
               $0,  $0,  $0,  $0,  $0,  $0,  $0,     { none }
               $0,  $0,  $0,  $0,  $0,  $0,  $0,     { none }
               $0,  $0,  $0,  $0,  $0,  $0,  $0,     { none }
               $0,  $0,  $0,  $0,  $0,  $0,  $0,     { none }
               $0,  $0,  $0,  $0,  $0,  $0,  $0,     { none }
               $0,  $0,  $0,  $0,  $0,  $0,  $0,     { none }
               $0,  $0,  $0,  $0,  $0,  $0,  $0,     { none }
               $0,  $0,  $0,  $0,  $0,  $0,  $0,     { none }
               $0,  $0,  $0,  $0,  $0,  $0,  $0,     { none }
               $0,  $0,  $0,  $0,  $0,  $0,  $0,     { none }
               $0,  $0,  $0,  $0,  $0,  $0,  $0,     { none }
               $0,  $0,  $0,  $0,  $0,  $0,  $0,     { none }
               $0,  $0,  $0,  $0,  $0,  $0,  $0,     { none }
               $00, $06, $0e, $10, $0e, $01, $1e,    { s caron}
               $0,  $0,  $0,  $0,  $0,  $0,  $0,     { none }
               $0,  $0,  $0,  $0,  $0,  $0,  $0,     { none }
               $0,  $0,  $0,  $0,  $0,  $0,  $0,     { none }
               $0,  $0,  $0,  $0,  $0,  $0,  $0,     { none }
               $0,  $0,  $0,  $0,  $0,  $0,  $0,     { none }
               $0,  $0,  $0,  $0,  $0,  $0,  $0,     { none }
               $0,  $0,  $0,  $0,  $0,  $0,  $0,     { none }
               $0,  $0,  $0,  $0,  $0,  $0,  $0,     { none }
               $0,  $0,  $0,  $0,  $0,  $0,  $0,     { none }
               $0,  $0,  $0,  $0,  $0,  $0,  $0,     { none }
               $0,  $0,  $0,  $0,  $0,  $0,  $0,     { none }
               $0,  $0,  $0,  $0,  $0,  $0,  $0,     { none }
               $0,  $0,  $0,  $0,  $0,  $0,  $0,     { none }
               $0,  $0,  $0,  $0,  $0,  $0,  $0,     { none }
               $0,  $0,  $0,  $0,  $0,  $0,  $0,     { none }
               $0,  $0,  $0,  $0,  $0,  $0,  $0,     { none }
               $0,  $0,  $0,  $0,  $0,  $0,  $0,     { none }
               $0,  $0,  $0,  $0,  $0,  $0,  $0,     { none }
               $0,  $0,  $0,  $0,  $0,  $0,  $0,     { none }
               $0,  $0,  $0,  $0,  $0,  $0,  $0,     { none }
               $0,  $0,  $0,  $0,  $0,  $0,  $0,     { none }
               $0,  $0,  $0,  $0,  $0,  $0,  $0,     { none }
               $0,  $0,  $0,  $0,  $0,  $0,  $0,     { none }
               $0,  $0,  $0,  $0,  $0,  $0,  $0,     { none }
               $0,  $0,  $0,  $0,  $0,  $0,  $0,     { none }
               $0,  $0,  $0,  $0,  $0,  $0,  $0,     { none }
               $0,  $0,  $0,  $0,  $0,  $0,  $0,     { none }
               $0,  $0,  $0,  $0,  $0,  $0,  $0,     { none }
               $0,  $0,  $0,  $0,  $0,  $0,  $0,     { none }
               $0,  $0,  $0,  $0,  $0,  $0,  $0,     { none }
               $0,  $0,  $0,  $0,  $0,  $0,  $0,     { none }
               $0,  $0,  $0,  $0,  $0,  $0,  $0,     { none }
               $0,  $0,  $0,  $0,  $0,  $0,  $0,     { none }
               $0,  $0,  $0,  $0,  $0,  $0,  $0,     { none }
               $0,  $0,  $0,  $0,  $0,  $0,  $0,     { none }
               $0,  $0,  $0,  $0,  $0,  $0,  $0,     { none }
               $0,  $0,  $0,  $0,  $0,  $0,  $0,     { none }

               $04, $02, $0e, $11, $1f, $11, $11,    { A' }
               $02, $04, $0e, $11, $1f, $11, $11,    { A´ }
               $04, $0a, $0e, $11, $1f, $11, $11,    { A^ }
               $05, $0a, $0e, $11, $1f, $11, $11,    { A~ }
               $0a, $00, $0e, $11, $1f, $11, $11,    { Ä }
               $04, $00, $0e, $11, $1f, $11, $11,    { Ao }
               $0f, $14, $14, $1f, $14, $14, $17,    { AE }
               $0e, $11, $10, $10, $11, $0e, $04,    { C, }
               $04, $02, $1f, $10,  $1e, $10, $1f,   { E' }
               $02, $04, $1f, $10,  $1e, $10, $1f,   { E´}
               $04, $0a, $1f, $10,  $1e, $10, $1f,   { Ê }
               $0a, $00, $1f, $10,  $1e, $10, $1f,   { Ë }
               $04, $02, $0e, $04, $04, $04, $0e,    { I' }
               $02, $04, $0e, $04, $04, $04, $0e,    { I´ }
               $04, $0a, $0e, $04, $04, $04, $0e,    { Î }
               $0a, $00, $0e, $04, $04, $04, $0e,    { Ï }

               $1e, $11, $11, $1d, $11, $11, $1e,    { D- }
               $05, $0a, $11, $19, $15, $13, $11,    { Ñ }
               $04, $02, $0e, $11, $11, $11, $0e,    { O' }
               $02, $04, $0e, $11, $11, $11, $0e,    { O´ }
               $04, $0a, $0e, $11, $11, $11, $0e,    { Ô }
               $05, $0a, $0e, $11, $11, $11, $0e,    { Õ }
               $0a, $00, $0e, $11, $11, $11, $0e,    { Ö }
               $00, $00, $11, $0a, $04, $0a, $11,    { x }
               $0e, $11, $13, $15, $19, $11, $0e,    { O/ }
               $04, $02, $11, $11, $11, $11, $0e,    { U' }
               $02, $04, $11, $11, $11, $11, $0e,    { U´ }
               $04, $0a, $11, $11, $11, $11, $0e,    { Û }
               $0a, $00, $11, $11, $11, $11, $0e,    { Ü }
               $02, $04, $11, $0a, $04, $04, $04,    { Y }
               $10, $1e, $11, $11, $1e, $10, $10,    { P }
               $1e, $11, $11, $1e, $11, $11, $16,    { Beta }

               $04, $02, $0e, $12, $12, $12, $0d,    { a' }
               $02, $04, $0e, $12, $12, $12, $0d,    { a´ }
               $04, $0a, $0e, $12, $12, $12, $0d,    { a^ }
               $05, $0a, $0e, $12, $12, $12, $0d,    { a~ }
               $0a, $00, $0e, $12, $12, $12, $0d,    { ä }
               $04, $00, $0e, $12, $12, $12, $0d,    { ao }
               $00, $00, $0e, $15, $17, $14, $0b,    { ae }
               $00, $0e, $10, $10, $11, $0e, $04,    { c, }
               $04, $02, $0e, $11, $1e, $10, $0e,    { e' }
               $02, $04, $0e, $11, $1e, $10, $0e,    { e´ }
               $04, $0a, $0e, $11, $1e, $10, $0e,    { e^ }
               $0a, $00, $0e, $11, $1e, $10, $0e,    { e¨ }
               $04, $02, $00, $04, $04, $04, $0e,    { i' }
               $02, $04, $00, $04, $04, $04, $0e,    { i´ }
               $04, $0a, $00, $04, $04, $04, $0e,    { i^ }
               $0a, $00, $00, $04, $04, $04, $0e,    { ï }

               $03, $01, $0d, $13, $11, $11, $0f,    { d- }
               $05, $0a, $16, $19, $11, $11, $11,    { n~ }
               $04, $02, $0e, $11, $11, $11, $0e,    { o' }
               $02, $04, $0e, $11, $11, $11, $0e,    { o´ }
               $04, $0a, $0e, $11, $11, $11, $0e,    { o^ }
               $05, $0a, $0e, $11, $11, $11, $0e,    { õ }
               $0a, $00, $0e, $11, $11, $11, $0e,    { ö }
               $00, $00, $00, $00, $00, $00, $00,    { none }
               $00, $00, $0e, $13, $15, $19, $0e,    { o/ }
               $04, $02, $11, $11, $11, $13, $0d,    { u' }
               $02, $04, $11, $11, $11, $13, $0d,    { u´ }
               $04, $0a, $11, $11, $11, $13, $0d,    { û }
               $0a, $00, $11, $11, $11, $13, $0d,    { ü }
               $02, $04, $11, $0a, $04, $04, $08,    { y' }
               $10, $10, $1e, $11, $1e, $10, $10,    { P }
               $0a, $00, $11, $0a, $04, $04, $08);   {  }




  SegSize: array[TMatrixLedStyle] of Integer = (1, 2, 3);

  SegX = 5;
  SegY = 7;
  ColorCmd = '%';

  ColorArray: array[1..16] of TAlphaColor = (
    TAlphaColorRec.Black, TAlphaColorRec.Maroon, TAlphaColorRec.Green, TAlphaColorRec.Olive, TAlphaColorRec.Navy, TAlphaColorRec.Purple,
    TAlphaColorRec.Teal, TAlphaColorRec.Gray, TAlphaColorRec.Silver, TAlphaColorRec.Red, TAlphaColorRec.Lime, TAlphaColorRec.Yellow,
    TAlphaColorRec.Blue, TAlphaColorRec.Fuchsia, TAlphaColorRec.Aqua, TAlphaColorRec.White);

  //Each color code is made out of a percentage charater and a combination
  //of a digit or a letter: for example "%CHello" will display all characters in clYellow.
  //Combinations are also possible: %CH%0ello. This will only display the
  //"H" in a different color.

  //Codes are as follows:
  //1 = clBlack       A = clRed
  //2 = clMaroon      B = clLime
  //3 = clGreen       C = clYellow
  //4 = clOlive       D = clBlue
  //5 = clNavy        E = clFuchsia
  //6 = clPurple      F = clAqua
  //7 = clTeal        G = clWhite
  //8 = clGray
  //9 = clSilver

  //Note: in order to reset to the default palette color use "%0", or
  //to display a % character use %%.

{ TText }

constructor TLEDText.Create(AOwner: TComponent);
begin
  inherited;
  FPalette := TLEDPalette.Create;
  FPalette.OnChange := OnPaletteChanged;
  FAutoScroll := false;
  {$IFDEF DELPHIXE6_LVL}
  FHorzTextAlign := TTextAlign.Center; // vgTextAlignCenter;
  FVertTextAlign := TTextAlign.Center; //vgTextAlignCenter;
  {$ELSE}
  FHorzTextAlign := TTextAlign.taCenter; // vgTextAlignCenter;
  FVertTextAlign := TTextAlign.taCenter; //vgTextAlignCenter;
  {$ENDIF}
  FWordWrap := true;
  FFont := TFont.Create;
  FFont.OnChanged := FontChanged;
  Fill.DefaultColor := $FF000000;
  Fill.Color := $FF000000;
  {$IFDEF DELPHIXE6_LVL}
  Stroke.DefaultKind := TBrushKind.None; // .DefaultStyle := vgBrushNone;
  Stroke.Kind := TBrushKind.None; // .Style := vgBrushNone;
  {$ELSE}
  Stroke.DefaultKind := TBrushKind.bkNone; // .DefaultStyle := vgBrushNone;
  Stroke.Kind := TBrushKind.bkNone; // .Style := vgBrushNone;
  {$ENDIF}

  SetBounds(0, 0, 245, 30);
  //Color := clBlack;
  FLeds := 15;
  FSpacing := 2;
  FMargin := 10;
  FLedStyle := ls14x20;
  FLedsVisible := True;
  FPosition := 1;
  FAlignment := vaLeftJustify;
  FTextStyle := tsUpperCase;
  FOrientation := voHorizontal;
  FScrollDirection := msdRightToLeft;
  FTimer := TTimer.Create(Self);
  FTimer.Enabled := false;
  FTimer.Interval := 500;
  FTimer.OnTimer := OnTimerEvent;

  LoadBitmaps;
end;

destructor TLEDText.Destroy;
begin
  FTimer.Enabled := False;
  FTimer.Free;
  FFont.Free;
  FPalette.Free;
  inherited;
end;

procedure TLEDText.DoScrollDone;
begin

end;

procedure TLEDText.LoadBitmaps;
begin
  case LedStyle of
    ls9x13:
    begin
      FLedw := 9;
      fLedh := 13;
    end;
    ls14x20:
    begin
      FLedw := 14;
      fLedh := 20;
    end;
    ls19x27:
    begin
      FLedw := 19;
      fLedh := 27;
    end;
  end;
end;

procedure TLEDText.Loaded;
begin
  inherited;
  UpdateAlignment;
  AdjustControlSize;
end;

procedure TLEDText.OnPaletteChanged(Sender: TObject);
begin
  LoadBitmaps;
  UpdateControlCanvas;
  Repaint;
end;

procedure TLEDText.OnTimerEvent(Sender: TObject);
begin
  if FScrollDirection = msdRightToLeft then
  begin
    if FPosition < Length(FChars) then
      Inc(FPosition) else
    begin
      DoScrollDone;
      FPosition := -FLeds + 1;
    end;
  end else
  begin
    if FPosition > -FLeds + 1 then
      Dec(FPosition) else
    begin
      DoScrollDone;
      FPosition := Length(FChars);
    end;
  end;
  UpdateControlCanvas;
end;

function TLEDText.GetData: TValue;
begin
  Result := Text;
end;

function TLEDText.GetTimeInterval: Integer;
begin
  Result := FTimer.Interval;
end;

procedure TLEDText.SetTimeInterval(const Value: Integer);
begin
  FTimer.Interval := Value;
end;

procedure TLEDText.SetData(const Value: TValue);
begin
  //Text := Value;
  Decode(Text);
end;

procedure TLEDText.FontChanged(Sender: TObject);
begin
  if FAutoSize then
    AdjustSize;
  Repaint;
end;

procedure TLEDText.Decode(S: string);
var
  I: Integer;
const
  {$IFDEF DELPHI_LLVM}
  j: Integer = 0;
  {$ELSE}
  j: Integer = 1;
  {$ENDIF}

  procedure PutChar(var S: string);
  begin
    FChars := FChars + S[j];
    FColors := FColors + FCurColor;
    Delete(S, 1, 1);
  end;

  procedure GetColor(var S: string);
  begin
    FCurColor := '-';
    if S <> '' then
    begin
      if (Upcase(S[j]) = '0') or
         (Upcase(S[j]) = '1') or
         (Upcase(S[j]) = '2') or
         (Upcase(S[j]) = '3') or
         (Upcase(S[j]) = '4') or
         (Upcase(S[j]) = '5') or
         (Upcase(S[j]) = '6') or
         (Upcase(S[j]) = '7') or
         (Upcase(S[j]) = '8') or
         (Upcase(S[j]) = '9') or

         (Upcase(S[j]) = 'A') or
         (Upcase(S[j]) = 'B') or
         (Upcase(S[j]) = 'C') or
         (Upcase(S[j]) = 'D') or
         (Upcase(S[j]) = 'E') or
         (Upcase(S[j]) = 'F') or
         (Upcase(S[j]) = 'G') then
        FCurColor := S[j];
      Delete(S, 1, 1);
    end;
  end;

begin
  FChars := '';
  FColors := '';
  FCurColor := '-';
  while Length(S) > 0 do
  begin
    if S[j] = ColorCmd then
    begin
      Delete(S, 1, 1);
      if (S <> '') and (S[j] = ColorCmd) then
        PutChar(S)
      else GetColor(S);
    end else PutChar(S);
  end;

  case FTextStyle of
    tsUpperCase: FChars := AnsiUpperCase(FChars);
    tsLowerCase: FChars := AnsiLowerCase(FChars);
    tsProperCase:
      begin
        FChars := AnsiLowerCase(FChars);
        if FChars <> '' then
        begin
          I := j;
          while (I < Length(FChars)) do
          begin
            if (I = j) or ((I > j) and (FChars[I - j] = #32)) then
              FChars[I] := Upcase(FChars[I]);
            Inc(I);
          end;
        end;
      end;
    tsAsIs:; //do nothing
  end;
end;

procedure TLEDText.Paint;
var
  R: TRectF;
  //M: TMatrix;
begin
  R := LocalRect;
  if (csDesigning in ComponentState) and not Locked and not FInPaintTo then
  begin
    Canvas.StrokeThickness := 1;
    Canvas.Stroke.Color := $A0909090;
    Canvas.DrawRect(R, 0, 0, AllCorners, AbsoluteOpacity);
    {$IFDEF DELPHIXE6_LVL}
    Canvas.StrokeDash := TStrokeDash.Dash; // vgDashDash;
    Canvas.Stroke.Kind := TBrushKind.Solid; // .Style := vgBrushSolid;
    Canvas.StrokeDash := TStrokeDash.Solid; // vgDashSolid;
    {$ELSE}
    Canvas.StrokeDash := TStrokeDash.sdDash; // vgDashDash;
    Canvas.Stroke.Kind := TBrushKind.bkSolid; // .Style := vgBrushSolid;
    Canvas.StrokeDash := TStrokeDash.sdSolid; // vgDashSolid;
    {$ENDIF}
  end;

  Canvas.Fill.Color := Fill.Color;
  {$IFDEF DELPHIXE6_LVL}
  Canvas.Fill.Kind := TBrushKind.Solid; // Style := vgBrushSolid;
  Canvas.FillRect(R, 0, 0, [TCorner.TopLeft, TCorner.TopRight, TCorner.BottomLeft, TCorner.BottomRight], AbsoluteOpacity, TCornerType.Round);
  {$ELSE}
  Canvas.Fill.Kind := TBrushKind.bkSolid; // Style := vgBrushSolid;
  Canvas.FillRect(R, 0, 0, [TCorner.crTopLeft, TCorner.crTopRight, TCorner.crBottomLeft, TCorner.crBottomRight], AbsoluteOpacity, TCornerType.ctRound);
  {$ENDIF}
  Canvas.Font.Assign(FFont);

  PaintLeds;
end;

procedure TLEDText.PaintLed(X, Y: Single; Ch: Char; AColor: TAlphaColor);
var
  R: TRectF;
  I, J, Index, W: Integer;
begin
  with Canvas do
  begin
    if Ch = #32 then Exit;
    Canvas.Fill.Color := AColor;
    {$IFDEF DELPHIXE6_LVL}
    Canvas.Fill.Kind := TBrushKind.Solid; // .Style := vgBrushSolid;
    {$ELSE}
    Canvas.Fill.Kind := TBrushKind.bkSolid; // .Style := vgBrushSolid;
    {$ENDIF}
    Index := ord(Ch) * 7;
    W := SegSize[FLedStyle];
    for I := 0 to 6 do
      for J := 0 to 4 do
      begin
        if CharState[Index + I] and (1 shl J) > 0 then
        begin
          R := RectF(X + FLedw - W - (J * Succ(W)), Y + (I * Succ(W)), W, W);
          R.Right := R.Left + R.Right;
          R.Bottom := R.Top + R.Bottom;

          {$IFDEF DELPHIXE6_LVL}
          Canvas.FillRect(R, 0, 0, [TCorner.TopLeft, TCorner.TopRight, TCorner.BottomLeft, TCorner.BottomRight], AbsoluteOpacity, TCornerType.Round);
          {$ELSE}
          Canvas.FillRect(R, 0, 0, [TCorner.crTopLeft, TCorner.crTopRight, TCorner.crBottomLeft, TCorner.crBottomRight], AbsoluteOpacity, TCornerType.ctRound);
          {$ENDIF}
        end;
      end;
  end;
end;

procedure TLEDText.PaintLeds;
var
  Cnt: Integer;
  I, J, K: Integer;
  X, Y, W, x1, y1: Double;
  R: TRectF;
  spc: integer;

  function GetColorValue(Ch: Char): TAlphaColor;
  var
    ColorIndex: Integer;
  begin
    ColorIndex := 0;
    case Upcase(Ch) of
      '0'..'9' : ColorIndex := ord(Ch) - 48;    // 48 = ord('0')
      'A'..'G' : ColorIndex := ord(Ch) - 55;   // 'A' = 41h = 65d  ; minus 10 = 55d
    end;
    if (ColorIndex < 1) or (ColorIndex > 16) then
        Result := FPalette.High  //TAlphaColorRec.Yellow
    else
        Result := ColorArray[ColorIndex];
  end;

begin
  if not AutoScroll then
    UpdateAlignment;

  if Orientation = voHorizontal then
  begin
    W := (FLedw * FLeds) +
         (FSpacing * Pred(FLeds));
    X := round((Width - W)) div 2;
    Y := round((Height - FLedh)) div 2;
  end else
  begin
    W := (FLedh * FLeds) +
         (FSpacing * Pred(FLeds));
    X := round((Width - FLedw)) div 2;
    Y := round((Height - W)) div 2;
  end;

  spc := 0;
  case LedStyle of
    ls9x13: spc := 2;
    ls14x20: spc := 3;
    ls19x27: spc := 4;
  end;

  {$IFDEF DELPHI_LLVM}
  Cnt := FPosition - 1;
  {$ELSE}
  Cnt := FPosition;
  {$ENDIF}
  for I := 0 to FLeds - 1 do
  begin
    if FLedsVisible then
    begin
      Canvas.Fill.Color := TAlphaColorRec.Gray;
      {$IFDEF DELPHIXE6_LVL}
      Canvas.Fill.Kind := TBrushKind.Solid;
      {$ELSE}
      Canvas.Fill.Kind := TBrushKind.bkSolid;
      {$ENDIF}
      x1 := x;
      for K := 1 to 5 do
      begin
        y1 := y;
        for j := 1 to 7 do
        begin
          R := RectF(x1, Y1, X1 + spc - 1, Y1 + spc - 1);
          {$IFDEF DELPHIXE6_LVL}
          Canvas.FillRect(R, 0, 0, [TCorner.TopLeft, TCorner.TopRight, TCorner.BottomLeft, TCorner.BottomRight], AbsoluteOpacity, TCornerType.Round);
          {$ELSE}
          Canvas.FillRect(R, 0, 0, [TCorner.crTopLeft, TCorner.crTopRight, TCorner.crBottomLeft, TCorner.crBottomRight], AbsoluteOpacity, TCornerType.ctRound);
          {$ENDIF}
          y1 := y1 + spc;
        end;
        x1 := x1 + spc;
      end;
    end;


    {$IFDEF DELPHI_LLVM}
    if (Cnt >= 0) and (Cnt < Length(FChars)) then
    {$ELSE}
    if (Cnt > 0) and (Cnt <= Length(FChars)) then
    {$ENDIF}
      PaintLed(X, Y, FChars[Cnt], GetColorValue(FColors[Cnt]));

    Inc(Cnt);

    if Orientation = voHorizontal then
      X := X + FLedw + FSpacing
    else
      Y := Y + FLedh + FSpacing;
  end;
end;

procedure TLEDText.SetWordWrap(const Value: Boolean);
begin
  if FWordWrap <> Value then
  begin
    FWordWrap := Value;
    Repaint;
  end;
end;

procedure TLEDText.UpdateAlignment;
begin
  case Alignment of
    vaLeftJustify: FPosition := 1;
    vaCenter: FPosition := -((FLeds - Length(FChars)) div 2) + 1;
    vaRightJustify: FPosition := -FLeds + Length(FChars) + 1;
  end;
end;

procedure TLEDText.UpdateControlCanvas;
begin
  if not (csLoading in ComponentState) then
    if FUpdating = 0 then Repaint;
end;

procedure TLEDText.SetAutoScroll(const Value: Boolean);
begin
  if (FAutoScroll <> Value) then
  begin
    FAutoScroll := Value;
    if not (csDesigning in ComponentState) then
    begin
      FTimer.Enabled := FAutoScroll;
      Repaint;
    end;
  end;
end;

procedure TLEDText.SetAutoSize(const Value: Boolean);
begin
  if FAutoSize <> Value then
  begin
    FAutoSize := Value;
    AdjustSize;
  end;
end;

procedure TLEDText.SetStretch(const Value: Boolean);
begin
  if FStretch <> Value then
  begin
    FStretch := Value;
    if Stretch then
      AutoSize := false;
    Repaint;
  end;
end;

procedure TLEDText.AdjustControlSize;
var
  Gap, Aw, Ah: Single;
begin
  Gap := (FLeds - 1) * FSpacing;
  if Orientation = voHorizontal then
  begin
    Aw := Gap + (FLeds * FLedw) + FMargin;
    Ah := FLedh + FMargin;
  end
  else
  begin
    Aw := FLedw + FMargin;
    Ah := Gap + (FLeds * FLedh) + FMargin;
  end;

  Width := aW;
  Height := aH;
end;

procedure TLEDText.AdjustSize;
var
  R: TRectF;
  C: TCanvas;
begin
  if FDisableAlign then
    Exit;
  FDisableAlign := True;

  C := Canvas;
  if FAutoSize and (FText <> '') then
  begin
    C.Font.Assign(FFont);
    if WordWrap then
      R := RectF(0, 0, Width, 1000)
    else
      R := RectF(0, 0, 1000, 1000);
    {$IFDEF DELPHIXE6_LVL}
    C.MeasureText(R, FText, WordWrap,  [], TTextAlign.Leading, TTextAlign.Leading);
    {$ELSE}
    C.MeasureText(R, FText, WordWrap,  [], TTextAlign.taLeading, TTextAlign.taLeading);
    {$ENDIF}

    if not WordWrap then
      Width := R.Right;
    {$IFDEF DELPHIXE6_LVL}
    if VertTextAlign <> TTextAlign.Center then
    {$ELSE}
    if VertTextAlign <> TTextAlign.taCenter then
    {$ENDIf}
      Height := R.Bottom;
  end;
  FDisableAlign := False;
end;

procedure TLEDText.SetFont(const Value: TFont);
begin
  FFont.Assign(Value);
  if FAutoSize then
    AdjustSize;
end;

procedure TLEDText.SetHorzTextAlign(const Value: TTextAlign);
begin
  if FHorzTextAlign <> Value then
  begin
    FHorzTextAlign := Value;
    Repaint;
  end;
end;

procedure TLEDText.SetVertTextAlign(const Value: TTextAlign);
begin
  if FVertTextAlign <> Value then
  begin
    FVertTextAlign := Value;
    Repaint;
  end;
end;

procedure TLEDText.SetText(const Value: String);
begin
  if FText <> Value then
  begin
    FText := Value;
    Decode(Text);
    if FAutoSize then
      AdjustSize;
    Repaint;
  end;
end;

procedure TLEDText.SetLeds(const Value: Integer);
begin
  if FLeds <> Value then
  begin
    FLeds := Value;
    Decode(Text);
    AdjustControlSize;
  end;
end;

procedure TLEDText.SetLedStyle(const Value: TMatrixLedStyle);
begin
  if FLedStyle <> Value then
  begin
    FLedStyle := Value;
    LoadBitmaps;
    AdjustControlSize;
  end;
end;

procedure TLEDText.SetLedsVisible(const Value: Boolean);
begin
  if FLedsVisible <> Value then
  begin
    FLedsVisible := Value;
    UpdateControlCanvas;
  end;
end;

procedure TLEDText.SetMargin(const Value: Integer);
begin
  if FMargin <> Value then
  begin
    FMargin := Value;
    AdjustControlSize;
  end;
end;

procedure TLEDText.SetOrientation(const Value: TVrOrientation);
begin
  if FOrientation <> Value then
  begin
    FOrientation := Value;
    AdjustControlSize;
  end;
end;

procedure TLEDText.SetPalette(const Value: TLEDPalette);
begin
  FPalette.Assign(Value);
end;

procedure TLEDText.SetAlignment(const Value: TVrAlignment);
begin
  if FAlignment <> Value then
  begin
    FAlignment := Value;
    UpdateControlCanvas;
  end;
end;

procedure TLEDText.SetSpacing(const Value: Integer);
begin
  if FSpacing <> Value then
  begin
    FSpacing := Value;
    AdjustControlSize;
  end;
end;

procedure TLEDText.SetTextStyle(const Value: TMatrixTextStyle);
begin
  if FTextStyle <> Value then
  begin
    FTextStyle := Value;
    Decode(Text);
    UpdateControlCanvas;
  end;
end;

//------------------------------------------------------------------------------

{ TLEDPalette }

constructor TLEDPalette.Create;
begin
  inherited Create;
  FLow := TAlphaColorRec.Green;
  FHigh := TAlphaColorRec.Lime;
end;

procedure TLEDPalette.SetLow(Value: TAlphaColor);
begin
  if FLow <> Value then
  begin
    FLow := Value;
    Changed;
  end;
end;

procedure TLEDPalette.SetHigh(Value: TAlphaColor);
begin
  if FHigh <> Value then
  begin
    FHigh := Value;
    Changed;
  end;
end;

procedure TLEDPalette.Assign(Source: TPersistent);
begin
  if (Source <> nil) and (Source is TLEDPalette) then
  begin
    BeginUpdate;
    try
      Low := TLEDPalette(Source).Low;
      High := TLEDPalette(Source).High;
    finally
      EndUpdate;
    end;
  end
  else
    inherited Assign(Source);
end;

function TLEDPalette.GetColors(Index: Integer): TColor;
begin
  Result := FLow;
  if Index > 0 then Result := FHigh;
end;

procedure TLEDPalette.Changed;
begin
  if FUpdateCount = 0 then
    if Assigned(FOnChange) then FOnChange(Self);
end;

procedure TLEDPalette.BeginUpdate;
begin
  Inc(FUpdateCount);
end;

procedure TLEDPalette.EndUpdate;
begin
  if FUpdateCount > 0 then Dec(FUpdateCount);
  Changed;
end;

 { TTMSFMXMatrixLabel }

procedure TTMSFMXMatrixLabel.ApplyStyle;
begin
  inherited;
  SetBounds(self.Position.X, self.Position.Y, self.Width, self.Height);
end;

constructor TTMSFMXMatrixLabel.Create(AOwner: TComponent);
begin
  inherited;
  FAutoScroll := False;
  FTimeInterval := 500;
  FScrollDirection := msdRightToLeft;
  Width := 281;
  Height := 30;
  ClipChildren := True;
end;

procedure TTMSFMXMatrixLabel.ApplyProperties(AControl: TFMXObject);
var
  led: TLEDText;
begin
  led := AControl.FindStyleResource('ledlabelstyle') as TLedText;
  if Assigned(led) then
  begin
    led.AutoScroll := AutoScroll;
    led.TimeInterval := TimeInterval;
    led.ScrollDirection := ScrollDirection;
    led.Text := Text;
  end;
end;

function TTMSFMXMatrixLabel.GetInstance: NativeUInt;
begin
  Result := HInstance;
end;

function TTMSFMXMatrixLabel.GetStyleObject: TFMXObject;
begin
  Result := inherited GetStyleObject;
  ApplyProperties(Result);
end;

function TTMSFMXMatrixLabel.GetVersion: String;
var
  vn: Integer;
begin
  vn := GetVersionNr;
  Result := IntToStr(Hi(Hiword(vn)))+'.'+IntToStr(Lo(Hiword(vn)))+'.'+IntToStr(Hi(Loword(vn)))+'.'+IntToStr(Lo(Loword(vn)));
end;

function TTMSFMXMatrixLabel.GetVersionNr: integer;
begin
  Result := MakeLong(MakeWord(BLD_VER,REL_VER),MakeWord(MIN_VER,MAJ_VER));
end;

procedure TTMSFMXMatrixLabel.SetAutoScroll(const Value: Boolean);
var
  T: TFmxObject;
begin
  FAutoScroll := Value;
  T := FindStyleResource('ledlabelstyle');
  if (T <> nil) and (T is TLEDText) then
    TLEDText(T).AutoScroll := Value;
end;

procedure TTMSFMXMatrixLabel.SetBounds(X, Y, AWidth, AHeight: Single);
var
  T: TFMXObject;
  Gap: Single;
  Aw, Ah: Single;
begin
  T := FindStyleResource('ledlabelstyle');

  if (T <> nil) and (T is TLEDText) then
  begin
    Gap := (TLedText(T).FLeds - 1) * TLedText(T).FSpacing;
    if TLedText(T).Orientation = voHorizontal then
    begin
      Aw := Gap + (TLedText(T).FLeds * TLedText(T).FLedw) + TLedText(T).FMargin;
      Ah := TLedText(T).FLedh + TLedText(T).FMargin;
    end
    else
    begin
      Aw := TLedText(T).FLedw + TLedText(T).FMargin;
      Ah := Gap + (TLedText(T).FLeds * TLedText(T).FLedh) + TLedText(T).FMargin;
    end;
    inherited SetBounds(X, Y, Aw, Ah)
  end
  else
    inherited;
end;

procedure TTMSFMXMatrixLabel.SetScrollDirection(
  const Value: TMatrixScrollDirection);
var
  T: TFmxObject;
begin
  FScrollDirection := Value;
  T := FindStyleResource('ledlabelstyle');
  if (T <> nil) and (T is TLEDText) then
    TLEDText(T).ScrollDirection := Value;
end;

procedure TTMSFMXMatrixLabel.SetText(const Value: string);
var
  T: TFmxObject;
begin
  inherited;
  FText := Value;
  T := FindStyleResource('ledlabelstyle');
  if (T <> nil) and (T is TLEDText) then
    TLEDText(T).Text := Value;
end;

procedure TTMSFMXMatrixLabel.SetTimeInterval(const Value: Integer);
var
  T: TFmxObject;
begin
  FTimeInterval := Value;
  T := FindStyleResource('ledlabelstyle');
  if (T <> nil) and (T is TLEDText) then
    TLEDText(T).TimeInterval := Value;
end;


initialization
  RegisterFmxClasses([TLEDText, TTMSFMXMatrixLabel]);
  RegisterAlphaColorIntegerConsts;
end.
