{$MODESWITCH DUPLICATELOCALS}
{$MODESWITCH AUTODEREF}
{
  TODO перейти на DDrawFont
}
unit DGraphFont;

interface

uses
  {$IFDEF DENG_USE_DRAW_OPENGL}{$IFDEF ANDROID}GLES,{$ELSE}GL, GLU,{$ENDIF}{$ENDIF}
  dtypes,
  dtexture2d,
  dvector2f,
  dvector2i,
  dstream,
  dstreamfile,
  DEng,
  DDraw,
  DGraphTex;

type
// deprecated, develope and use TFont
TGraphFont = packed object
  Tex: TGraphTex;
  Size: TVec2i;
  Spacing: Integer;
end;

TGraphFontHelper = class helper(TGraphTexHelper) for TGraph
  function UploadFont(const Data: TData): TGraphFont; overload;
  function UploadFont(const FileName: TString): TGraphFont; overload;
  procedure FreeFont(const Font: TGraphFont);
  function DrawText(const Font: TGraphFont;
    const P: TVec2f;
    const S: TString;
    W: Single = 0): TVec2f; overload;
  function GetTextSize(const Font: TGraphFont; const S: TString): TVec2f;
end;

PFont = ^TFont;
TFont = object
private
  FEng: TEngine;
public
  constructor Init(Eng: TEngine);
  destructor Done; virtual;
  function CharToIndex(const C: Cardinal): LongInt; virtual;
  function CharWidth(const C: Cardinal): LongInt; virtual;
  function CharHeight(const C: Cardinal): LongInt; virtual;
  function Width(const Line: AnsiString): LongInt; virtual;
  function Height(const Line: AnsiString): LongInt; virtual;
  // returns size of rendered char
  function DrawChar(const P: TVec2i; I: LongInt): TVec2i; overload;
  // draw utf-8 string
  procedure Draw(const P: TVec2i; const Line: AnsiString); overload;
  procedure DrawP(var P: TVec2i; const Line: AnsiString); overload;
end;

TFontCP1251Grid = object(TFont)
public
  constructor Init(
        Eng: TEngine;
        const FileName: AnsiString;
        Spacing: LongInt);
end;

implementation

function TGraphFontHelper.UploadFont(const Data: TData): TGraphFont;
begin
  Result.Tex := Self.UploadTex(Data, False);
  Result.Size := Vec2i(Result.Tex.Width div 16, Result.Tex.Height div 16);
  Result.Spacing := 1;
end;

function TGraphFontHelper.UploadFont(const FileName: TString): TGraphFont;
begin
  Result.Tex := Self.UploadTex(FileName, False);
  Result.Size := Vec2i(Result.Tex.Width div 16, Result.Tex.Height div 16);
  Result.Spacing := 1;
end;

procedure TGraphFontHelper.FreeFont(const Font: TGraphFont);
begin
  FreeTex(Font.Tex);
end;

function TGraphFontHelper.DrawText(const Font: TGraphFont;
  const P: TVec2f;
  const S: TString;
  W: Single = 0): TVec2f;
var
  I: Integer;
  T: TVec2i;
  Position: TVec2f;
begin
  Position := P;
  for I := 1 to Length(S) do begin
    if W <> 0 then begin
      if Position.X + Font.Size.X - P.X > W then begin
        Position.X := P.X;
        Position.Y := Position.Y + Font.Size.Y;
      end;
    end;
    T.X := (Ord(S[I]) mod 16) * Font.Size.X;
    T.Y := (Ord(S[I]) div 16) * Font.Size.Y;
    DrawTex(Font.Tex, Position, Vec2f(Font.Size.X, Font.Size.Y), T, Font.Size);
    Position := Add2f(Position, Vec2f(Font.Size.X + Font.Spacing, 0));
  end;
  Result := Position;
end;

function TGraphFontHelper.GetTextSize(const Font: TGraphFont; const S: TString): TVec2f;
begin
  Result := Vec2f(Length(S) * (Font.Size.X + Font.Spacing), Font.Size.Y);
end;

constructor TFont.Init(Eng: TEngine);
begin
  FEng := Eng;
end;

destructor TFont.Done;
begin
end;

function TFont.CharToIndex(const C: Cardinal): LongInt;
begin
  Result := C mod 256;
end;

function TFont.CharWidth(const C: Cardinal): LongInt;
begin
  Result := 0;
end;

function TFont.CharHeight(const C: Cardinal): LongInt;
begin
  Result := 0;
end;

function TFont.Width(const Line: AnsiString): LongInt;
begin
  Result := 0;
end;

function TFont.Height(const Line: AnsiString): LongInt;
begin
  Result := 0;
end;

function TFont.DrawChar(const P: TVec2i; I: LongInt): TVec2i;
begin
  Result := Vec2i(0, 0);
end;

procedure TFont.Draw(const P: TVec2i; const Line: AnsiString);
var
  T: TVec2i;
begin
  T := P;
  DrawP(T, Line);
end;

procedure TFont.DrawP(var P: TVec2i; const Line: AnsiString);
var
  I, Index: LongInt;
  S: TVec2i;
begin
  // TODO utf-8
  for I := 1 to Length(Line) do begin
    Index := CharToIndex(Ord(Line[I]));
    P.X := P.X + DrawChar(P, Index).X;
  end;
end;

constructor TFontCP1251Grid.Init(
      Eng: TEngine;
      const FileName: AnsiString;
      Spacing: LongInt);
begin
  inherited Init(Eng);
end;

end.
