Guest User

Untitled

a guest
Nov 11th, 2012
197
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Delphi 8.85 KB | None | 0 0
  1. unit UCharsetPool;
  2.  
  3. interface
  4.  
  5. uses
  6.   Types,
  7.   CoreExported,
  8.   UPool,
  9.   UTexturePool;
  10.  
  11. type
  12.   TCharsetPool = class;
  13.  
  14.   TCharset = class (TPoolItem, ICharset)
  15.     private type
  16.       TChar = packed record
  17.         X: Word;
  18.       end;
  19.       TLine = packed record
  20.         Y, FirstChar: Word;
  21.         Chars: packed array of TChar;
  22.       end;
  23.       TPage = record
  24.         Texture: ITexture;
  25.         FirstChar: Integer;
  26.         Lines: array of TLine;
  27.       end;
  28.       TCharLine = array of record
  29.         Texture: Pointer;
  30.         X,Y, Width: Integer;
  31.       end;
  32.       PPixelLine = ^TPixelLine;
  33.       TPixelLine = array [0..$FFFFFF] of Cardinal;
  34.  
  35.     private
  36.       FTexturePool: TTexturePool;
  37.       FCoreWindow: Pointer;
  38.       FPages: array of TPage;
  39.       FHeight: Integer;
  40.       FCharLineWidth: Integer;
  41.       FCount: Integer;
  42.  
  43.     protected
  44.       function BuildCharLine (Str: PWideChar): TCharLine;
  45.  
  46.     public
  47.       constructor Create (Pool: TCharsetPool; Path: PWideChar);
  48.       destructor Destroy; override;
  49.  
  50.     procedure BuildStrTexture
  51.                 (Str: PWideChar;
  52.                  TextColor, BgColor: Cardinal;
  53.                  Align: TFloatPoint;
  54.                  out Texture: ITexture;
  55.                  out Extent, Offset: TFloatPoint); stdcall;
  56.   end;
  57.  
  58.   TCharsetPool = class (TPool, ICharsetPool)
  59.     private
  60.       FTexturePool: TTexturePool;
  61.       FCoreWindow: Pointer;
  62.  
  63.     protected
  64.       function CreateItem (Path: PWideChar): TPoolItem; override;
  65.  
  66.     public
  67.       constructor Create (Root: IInterface; TexturePool: TTexturePool);
  68.       destructor Destroy; override;
  69.  
  70.     procedure LoadCharset (Path: PWideChar; out Charset: ICharset); stdcall;
  71.   end;
  72.  
  73. implementation
  74.  
  75. uses
  76.   SysUtils,
  77.   Direct3D9;
  78.  
  79. function TCharset.BuildCharLine;
  80. var
  81.   i: Integer;
  82.   Page, Line, Char: Integer;
  83.  
  84.   procedure FindPage (Ch: Word);
  85.   begin
  86.     Page := Length (FPages) - 1;
  87.     while FPages [Page].FirstChar > Ch do
  88.       Dec (Page);
  89.   end;
  90.   procedure FindLine (Ch: Word);
  91.   begin
  92.     FindPage (Ch);
  93.     Line := Length (FPages [Page].Lines) - 1;
  94.     while FPages [Page].Lines [Line].FirstChar > Ch do
  95.       Dec (Line);
  96.   end;
  97.   procedure FindChar (Ch: Word);
  98.   begin
  99.     FindLine (Ch);
  100.     Char := Ch - FPages [Page].Lines [Line].FirstChar;
  101.   end;
  102. begin
  103.   FCharLineWidth := 0;
  104.   SetLength (Result, StrLen (Str));
  105.   for i := 0 to Length (Result) - 1 do
  106.   begin
  107.     FindChar (Word (Str [i]));
  108.     with Result [i] do
  109.     begin
  110.       Texture := Pointer (FPages [Page].Texture);
  111.       X := FPages [Page].Lines [Line].Chars [Char].X;
  112.       Y := FPages [Page].Lines [Line].Y;
  113.       Width := FPages [Page].Lines [Line].Chars [Char + 1].X - X;
  114.       FCharLineWidth := FCharLineWidth + Width;
  115.     end;
  116.   end;
  117. end;
  118.  
  119. constructor TCharset.Create;
  120. const
  121.   PageStart = 8;
  122.   PageInc = 2;
  123.   LineStart = 200;
  124.   LineInc = 20;
  125.   CharStart = 300;
  126.   CharInc = 50;
  127. var
  128.   Input: Text;
  129.   NextChar: Integer;
  130.   Str: string;
  131.   Cmd: string;
  132.   Tag: Integer;
  133.   CurrentPage, CurrentLine, CurrentChar: Integer;
  134.  
  135.   procedure Err (Condition: Boolean = True);
  136.   begin
  137.     if Condition
  138.     then
  139.       raise Exception.Create('Invalid input file: "' + string (Path) + '".');
  140.   end;
  141.   procedure CmdPage;
  142.   begin
  143.     if CurrentPage <> -1
  144.     then
  145.       SetLength (FPages [CurrentPage].Lines, CurrentLine + 1);
  146.     CurrentPage := Tag;
  147.     while CurrentPage >= Length (FPages) do
  148.       SetLength (FPages, Length (FPages) + PageInc);
  149.     SetLength (FPages [CurrentPage].Lines, LineStart);
  150.     Pool.FTexturePool.LoadTexture (PWideChar (string (Path) + '.' + IntToStr (CurrentPage) + '.png'), FPages [CurrentPage].Texture);
  151.     FPages [CurrentPage].FirstChar := NextChar;
  152.     CurrentLine := -1;
  153.     CurrentChar := -1;
  154.   end;
  155.   procedure CmdHeight;
  156.   begin
  157.     FHeight := Tag;
  158.   end;
  159.   procedure CmdLine;
  160.   begin
  161.     CurrentLine := Tag;
  162.     while CurrentLine >= Length (FPages [CurrentPage].Lines) do
  163.       SetLength (FPages [CurrentPage].Lines, Length (FPages [CurrentPage].Lines) + LineInc);
  164.     FPages [CurrentPage].Lines [CurrentLine].FirstChar := NextChar;
  165.     SetLength (FPages [CurrentPage].Lines [CurrentLine].Chars, CharStart);
  166.     CurrentChar := 0;
  167.   end;
  168.   procedure CmdY;
  169.   begin
  170.     FPages [CurrentPage].Lines [CurrentLine].Y := Tag;
  171.   end;
  172.   procedure CmdX;
  173.   begin
  174.     while CurrentChar >= Length (FPages [CurrentPage].Lines [CurrentLine].Chars) do
  175.       SetLength (FPages [CurrentPage].Lines [CurrentLine].Chars, Length (FPages [CurrentPage].Lines [CurrentLine].Chars) + CharInc);
  176.     FPages [CurrentPage].Lines [CurrentLine].Chars [CurrentChar].X := Tag;
  177.     Inc (CurrentChar);
  178.     Inc (NextChar);
  179.   end;
  180.   procedure CmdWidth;
  181.   begin
  182.     SetLength (FPages [CurrentPage].Lines [CurrentLine].Chars, CurrentChar + 1);
  183.     FPages [CurrentPage].Lines [CurrentLine].Chars [CurrentChar].X := Tag;
  184.   end;
  185.   procedure ProcessStr;
  186.   var
  187.     CPos: Integer;
  188.   begin
  189.     CPos := Pos ('=', Str);
  190.     Err (CPos = 0);
  191.     Cmd := UpperCase (Trim (Copy (Str, 1, CPos - 1)));
  192.     Str := Trim (Copy (Str, CPos + 1, MaxInt));
  193.     Val (Str, Tag, CPos);
  194.     Err (CPos <> 0);
  195.     if Cmd = 'X'
  196.     then
  197.       CmdX
  198.     else if Cmd = 'LINE'
  199.     then
  200.       CmdLine
  201.     else if Cmd = 'Y'
  202.     then
  203.       CmdY
  204.     else if Cmd = 'WIDTH'
  205.     then
  206.       CmdWidth
  207.     else if Cmd = 'PAGE'
  208.     then
  209.       CmdPage
  210.     else if Cmd = 'HEIGHT'
  211.     then
  212.       CmdHeight
  213.     else
  214.       Err;
  215.   end;
  216. begin
  217.   inherited Create (Pool, Path);
  218.   FTexturePool := Pool.FTexturePool;
  219.   FCoreWindow := Pool.FCoreWindow;
  220.   AssignFile (Input, string (Path) + '.charset');
  221.   Reset (Input);
  222.  
  223.   SetLength (FPages, PageStart);
  224.   CurrentPage := -1;
  225.   NextChar := 0;
  226.   while NextChar <> $10000 do
  227.   begin
  228.     ReadLn (Input, Str);
  229.     ProcessStr;
  230.   end;
  231.   ReadLn (Input, Str);
  232.   ProcessStr;
  233.   SetLength (FPages [CurrentPage].Lines [CurrentLine].Chars, CurrentChar + 1);
  234.   SetLength (FPages [CurrentPage].Lines, CurrentLine + 1);
  235.   SetLength (FPages, CurrentPage + 1);
  236.  
  237.   Close (Input);
  238. end;
  239.  
  240. destructor TCharset.Destroy;
  241. var
  242.   i: Integer;
  243. begin
  244.   for i := 0 to Length (FPages) - 1 do
  245.     FPages [i].Texture := nil;
  246.   inherited Destroy;
  247. end;
  248.  
  249. function CorrectSize (X: Integer): Integer;
  250. begin
  251.   Result := 1;
  252.   Inc (X);
  253.   while X >= 1 do
  254.   begin
  255.     Result := Result shl 1;
  256.     X := X shr 1;
  257.   end;
  258. end;
  259.  
  260. procedure TCharset.BuildStrTexture;
  261. var
  262.   CharLine: TCharLine;
  263.   TexPath: string;
  264.   Source, Target: TD3DLockedRect;
  265.   SrcRect, TgtRect: TRect;
  266.   i, X,Y, Position: Integer;
  267.   D3DTex, CharTex: IDirect3DTexture9;
  268.   SrcLine, TgtLine: PPixelLine;
  269.   Size, WinSize: TPoint;
  270. begin
  271.   Inc (FCount);
  272.   TexPath := IntToStr (Integer (Self)) + IntToStr (FCount);
  273.   CharLine := BuildCharLine (Str);
  274.   Size.X := CorrectSize (FCharLineWidth);
  275.   Size.Y := CorrectSize (FHeight);
  276.   FTexturePool.CreateTexture (PWideChar (TexPath), Size.X, Size.Y, D3DFMT_A8R8G8B8, Texture);
  277.   D3DTex := Texture.Direct3DTexture;
  278.   FillChar (Target, SizeOf (TD3DLockedRect), 0);
  279.   TgtRect.Top := 0;
  280.   TgtRect.Left := 0;
  281.   TgtRect.BottomRight := Size;
  282.   ED3DError.Check (D3DTex.LockRect (0, Target, @TgtRect, 0));
  283.   for i := 0 to Size.Y - 1 do
  284.     FillChar (Pointer (Integer (Target.pBits) + i * Target.Pitch)^, 4 * Size.X, 0);
  285.   Position := 0;
  286.   for i := 0 to Length (CharLine) - 1 do
  287.   begin
  288.     SrcRect.Left := CharLine [i].X;
  289.     SrcRect.Top := CharLine [i].Y;
  290.     SrcRect.Right := TgtRect.Left + CharLine [i].Width;
  291.     SrcRect.Bottom := TgtRect.Top + FHeight;
  292.     CharTex := ITexture (CharLine [i].Texture).Direct3DTexture;
  293.     ED3DError.Check (CharTex.LockRect (0, Source, @SrcRect, D3DLOCK_READONLY));
  294.     SrcLine := Source.pBits;
  295.     TgtLine := Pointer (Integer (Target.pBits) + 4 * Position);
  296.     for Y := 0 to FHeight - 1 do
  297.     begin
  298.       for X := 0 to CharLine [i].Width - 1 do
  299.         if SrcLine [X] and $FF = 0
  300.         then
  301.           TgtLine [X] := TextColor
  302.         else
  303.           TgtLine [X] := BgColor;
  304.       SrcLine := Pointer (Integer (SrcLine) + Source.Pitch);
  305.       TgtLine := Pointer (Integer (TgtLine) + Target.Pitch);
  306.     end;
  307.     ED3DError.Check (CharTex.UnlockRect (0));
  308.     Position := Position + CharLine [i].Width;
  309.   end;
  310.   ED3DError.Check (D3DTex.UnlockRect (0));
  311.   D3DTex := nil;
  312.   CharTex := nil;
  313.   WinSize := ICoreWindow (FCoreWindow).Size;
  314.   Extent := TFloatPoint (Size) / WinSize.X;
  315.   Offset.X := (Size.X + FCharLineWidth * (- 1 + Align.X)) / WinSize.X;
  316.   Offset.Y := - (Size.Y + FHeight * (- 1 + Align.Y)) / WinSize.X;
  317. end;
  318.  
  319.  
  320.  
  321. function TCharsetPool.CreateItem;
  322. begin
  323.   Result := TCharset.Create (Self, Path);
  324. end;
  325.  
  326. constructor TCharsetPool.Create;
  327. begin
  328.   inherited Create (Root);
  329.   FCoreWindow := Pointer (Root);
  330.   FTexturePool := TexturePool;
  331. end;
  332.  
  333. destructor TCharsetPool.Destroy;
  334. begin
  335.   inherited Destroy;
  336. end;
  337.  
  338. procedure TCharsetPool.LoadCharset;
  339. begin
  340.   Charset := LoadItem (Path) as ICharset;
  341. end;
  342.  
  343. end.
Advertisement
Add Comment
Please, Sign In to add comment