123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318 |
- {
- This file is part of the Free Pascal run time library.
- Copyright (c) 2003 by the Free Pascal development team
- Basic canvas definitions.
- See the file COPYING.FPC, included in this distribution,
- for details about the copyright.
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- **********************************************************************}
- {$mode objfpc}{$h+}
- unit ftfont;
- interface
- uses SysUtils, Classes, FPCanvas, fpimgcmn, freetype, freetypeh;
- type
- FreeTypeFontException = class (TFPFontException);
- TFreeTypeFont = class (TFPCustomDrawFont)
- private
- FResolution : longword;
- FAntiAliased : boolean;
- FLastText : TStringBitmaps;
- FIndex, FFontID : integer;
- FFace : PFT_Face;
- FAngle : real;
- procedure DrawChar (x,y:integer; data:PByteArray; pitch, width, height:integer);
- procedure DrawCharBW (x,y:integer; data:PByteArray; pitch, width, height:integer);
- procedure ClearLastText;
- protected
- procedure SetName (AValue:string); override;
- procedure SetIndex (AValue : integer);
- procedure SetSize (AValue : integer); override;
- function GetFlags (index:integer) : boolean; override;
- procedure SetFlags (index:integer; AValue:boolean); override;
- procedure DoAllocateResources; override;
- procedure DoDeAllocateResources; override;
- procedure DoCopyProps (From:TFPCanvasHelper); override;
- procedure DoDrawText (atx,aty:integer; atext:string); override;
- procedure DoGetTextSize (text:string; var w,h:integer); override;
- function DoGetTextHeight (text:string) : integer; override;
- function DoGetTextWidth (text:string) : integer; override;
- procedure GetText (aText:string);
- procedure GetFace;
- public
- constructor create; override;
- destructor Destroy; override;
- property FontIndex : integer read FIndex write SetIndex;
- property Resolution : longword read FResolution write FResolution;
- property AntiAliased : boolean read FAntiAliased write FAntiAliased;
- property Angle : real read FAngle write FAngle;
- end;
- var
- FontMgr : TFontManager;
- procedure InitEngine;
- procedure DoneEngine;
- implementation
- uses fpimage;
- procedure InitEngine;
- begin
- if not assigned (FontMgr) then
- FontMgr := TFontManager.create;
- end;
- procedure DoneEngine;
- begin
- if assigned (FontMgr) then
- FontMgr.Free;
- end;
- constructor TFreeTypeFont.Create;
- begin
- inherited;
- FFontID := -1;
- FAntiAliased := True;
- FResolution := DefaultResolution;
- end;
- destructor TFreeTypeFont.Destroy;
- begin
- ClearLastText;
- inherited Destroy;
- end;
- procedure TFreeTypeFont.DoCopyProps (From:TFPCanvasHelper);
- var f : TFreeTypeFont;
- begin
- inherited;
- if from is TFreeTypeFont then
- begin
- f := TFreeTypeFont(from);
- FIndex := F.Findex;
- FAntiAliased := f.FAntiAliased;
- FResolution := f.FResolution;
- FAngle := f.FAngle;
- end;
- end;
- procedure TFreeTypeFont.SetName (AValue:string);
- begin
- inherited;
- ClearLastText;
- if allocated then
- FFontID := FontMgr.RequestFont(Name, FIndex);
- end;
- procedure TFreeTypeFont.SetIndex (AValue : integer);
- begin
- FIndex := AValue;
- ClearLastText;
- if allocated then
- FFontID := FontMgr.RequestFont(Name, FIndex);
- end;
- procedure TFreeTypeFont.SetSize (AValue : integer);
- begin
- ClearLastText;
- inherited;
- end;
- procedure TFreeTypeFont.ClearLastText;
- begin
- if assigned(FLastText) then
- begin
- FLastText.Free;
- FlastText := nil;
- end;
- end;
- procedure TFreeTypeFont.DoAllocateResources;
- begin
- InitEngine;
- FFontID := FontMgr.RequestFont(Name, FIndex);
- end;
- procedure TFreeTypeFont.DoDeAllocateResources;
- begin
- end;
- procedure TFreeTypeFont.DoGetTextSize (text:string; var w,h:integer);
- var r : TRect;
- begin
- GetText (text);
- FLastText.GetBoundRect (r);
- with r do
- begin
- w := right - left;
- h := top - bottom;
- end;
- end;
- function TFreeTypeFont.DoGetTextHeight (text:string) : integer;
- var r : TRect;
- begin
- GetText (text);
- FLastText.GetBoundRect (r);
- with r do
- result := top - bottom;
- end;
- function TFreeTypeFont.DoGetTextWidth (text:string) : integer;
- var r : TRect;
- begin
- GetText (text);
- FLastText.GetBoundRect (r);
- with r do
- result := right - left;
- end;
- procedure TFreeTypeFont.SetFlags (index:integer; AValue:boolean);
- begin
- if not (index in [5,6]) then // bold,italic
- inherited SetFlags (index, AValue);
- end;
- procedure TFreeTypeFont.GetFace;
- begin
- if not assigned(FFace) then
- FFace := FontMgr.GetFreeTypeFont (FFontID);
- end;
- function TFreeTypeFont.GetFlags (index:integer) : boolean;
- begin
- if index = 5 then //bold
- begin
- GetFace;
- result := (FFace^.style_flags and FT_STYLE_FLAG_BOLD) <> 0;
- end
- else if index = 6 then //italic
- begin
- GetFace;
- result := (FFace^.style_flags and FT_STYLE_FLAG_ITALIC) <> 0;
- end
- else
- result := inherited GetFlags (index);
- end;
- procedure TFreeTypeFont.GetText (aText:string);
- var b : boolean;
- begin
- if assigned (FLastText) then
- begin
- if CompareStr(FLastText.Text,aText) <> 0 then
- begin
- FLastText.Free;
- b := true;
- end
- else
- begin
- if FAntiAliased then
- b := (FLastText.mode <> bt256Gray)
- else
- b := (FLastText.mode <> btBlackWhite);
- if b then
- FLastText.Free;
- end;
- end
- else
- b := true;
- if b then
- begin
- FontMgr.Resolution := FResolution;
- if FAntiAliased then
- FLastText := FontMgr.GetStringGray (FFontId, aText, Size, Angle)
- else
- FLastText := FontMgr.GetString (FFontId, aText, Size, Angle);
- end;
- end;
- procedure TFreeTypeFont.DoDrawText (atX,atY:integer; atext:string);
- var r,i : integer;
- f : longint;
- begin
- GetText (atext);
- with FLastText do
- for r := 0 to count-1 do
- with Bitmaps[r]^ do
- begin
- if mode = btBlackWhite then
- DrawCharBW (atX+x, atY+y, data, pitch, width, height)
- else
- DrawChar (atX+x, atY+y, data, pitch, width, height);
- end;
- end;
- const
- //bits : array[0..7] of byte = (1,2,4,8,16,32,64,128);
- bits : array[0..7] of byte = (128,64,32,16,8,4,2,1);
- procedure TFreeTypeFont.DrawChar (x,y:integer; data:PByteArray; pitch, width, height:integer);
- procedure Combine (canv:TFPCustomCanvas; x,y:integer; c : TFPColor; t:longword);
- var a,r,g,b:longword;
- begin
- if t = 255 then
- canv.colors[x,y] := c
- else if t <> 0 then
- begin
- with canv.colors[x,y] do
- begin
- a := 255-t;
- r := ((red * a) + (c.red * t)) div 255;
- g := ((green * a) + (c.green * t)) div 255;
- b := ((blue * a) + (c.blue * t)) div 255;
- end;
- canv.colors[x,y] := FPImage.FPColor(r,g,b,alphaOpaque);
- end;
- end;
- var b,rx,ry : integer;
- begin
- b := 0;
- for ry := 0 to height-1 do
- begin
- for rx := 0 to width-1 do
- combine (canvas, x+rx, y+ry, FPColor, data^[b+rx]);
- inc (b, pitch);
- end;
- end;
- procedure TFreeTypeFont.DrawCharBW (x,y:integer; data:PByteArray; pitch, width, height:integer);
- var rb : byte;
- rx,ry,b,l : integer;
- begin
- b := 0;
- for ry := 0 to height-1 do
- begin
- l := 0;
- for rx := 0 to width-1 do
- begin
- rb := rx mod 8;
- if (data^[b+l] and bits[rb]) <> 0 then
- canvas.colors[x+rx,y+ry] := FPColor;
- if rb = 7 then
- inc (l);
- end;
- inc (b, pitch);
- end;
- end;
- finalization
- DoneEngine;
- end.
|