From 15deb6f3f502e048d4aa86cb36948e9810adcc7a Mon Sep 17 00:00:00 2001 From: sekelsenmat Date: Sat, 3 Mar 2012 14:33:27 +0000 Subject: [PATCH] Adds the LazFreeType drawer to the LCL git-svn-id: trunk@35668 - --- .gitattributes | 1 + lcl/alllclunits.pp | 12 +- lcl/lazfreetypeintfdrawer.pas | 234 ++++++++++++++++++++++++++++++++++ lcl/lclbase.lpk | 9 +- 4 files changed, 249 insertions(+), 7 deletions(-) create mode 100644 lcl/lazfreetypeintfdrawer.pas diff --git a/.gitattributes b/.gitattributes index 51b0adf156..2bd1d39563 100644 --- a/.gitattributes +++ b/.gitattributes @@ -5950,6 +5950,7 @@ lcl/lazcanvas.pas svneol=native#text/pascal lcl/lazconfigstorage.pas svneol=native#text/pascal lcl/lazdeviceapis.pas svneol=native#text/plain lcl/lazdialogs.pas svneol=native#text/plain +lcl/lazfreetypeintfdrawer.pas svneol=native#text/plain lcl/lazhelphtml.pas svneol=native#text/pascal lcl/lazhelpintf.pas svneol=native#text/pascal lcl/lazlinkedlist.pas svneol=native#text/pascal diff --git a/lcl/alllclunits.pp b/lcl/alllclunits.pp index f0ee0bb3c3..30355c94c1 100644 --- a/lcl/alllclunits.pp +++ b/lcl/alllclunits.pp @@ -2,7 +2,7 @@ This source is only used to compile and install the package. } -unit alllclunits; +unit alllclunits; interface @@ -26,15 +26,15 @@ uses WSStdCtrls, WSToolwin, ActnList, Arrow, AsyncProcess, ButtonPanel, Buttons, Calendar, RegisterLCL, ValEdit, lazcanvas, lazdialogs, lazregions, customdrawn_common, customdrawncontrols, customdrawndrawers, lazdeviceapis, - LDockTree, LazarusPackageIntf; + LDockTree, LazFreeTypeIntfDrawer, LazarusPackageIntf; implementation -procedure Register; +procedure Register; begin - RegisterUnit('RegisterLCL', @RegisterLCL.Register); -end; + RegisterUnit('RegisterLCL', @RegisterLCL.Register); +end; initialization - RegisterPackage('LCLBase', @Register); + RegisterPackage('LCLBase', @Register); end. diff --git a/lcl/lazfreetypeintfdrawer.pas b/lcl/lazfreetypeintfdrawer.pas new file mode 100644 index 0000000000..7c363b5844 --- /dev/null +++ b/lcl/lazfreetypeintfdrawer.pas @@ -0,0 +1,234 @@ +unit LazFreeTypeIntfDrawer; + +{$mode objfpc}{$H+} + +interface + +uses + Classes, SysUtils, Graphics, EasyLazFreeType, IntfGraphics, FPimage; + +type + { TIntfFreeTypeDrawer } + + TIntfFreeTypeDrawer = class(TFreeTypeDrawer) + private + FColor: TFPColor; + protected + procedure RenderDirectly(x, y, tx: integer; data: pointer); + procedure RenderDirectlyClearType(x, y, tx: integer; data: pointer); + procedure MergeColorOver(var merge: TFPColor; const c: TFPColor); inline; + procedure ClearTypePixel(x,y: integer; Cr,Cg,Cb: byte; Color: TFPColor); + public + Destination: TLazIntfImage; + ClearTypeRGBOrder: boolean; + constructor Create(ADestination: TLazIntfImage); + procedure ClippedDrawPixel(x,y: integer; const c: TFPColor); + procedure DrawPixel(x,y: integer; const c: TFPColor); + procedure DrawVertLine(x,y1,y2: integer; const c: TFPColor); + procedure DrawText(AText: string; AFont: TFreeTypeRenderableFont; x,y: single; AColor: TFPColor; AOpacity: Byte); override; overload; + procedure DrawText(AText: string; AFont: TFreeTypeRenderableFont; x,y: single; AColor: TFPColor); overload; + destructor Destroy; override; + end; + +implementation + +uses LCLType; + +{ TIntfFreeTypeDrawer } + +procedure TIntfFreeTypeDrawer.MergeColorOver(var merge: TFPColor; const c: TFPColor); +var + a1f, a2f, a12, a12m: cardinal; +begin + a12 := 65534 - ((not merge.alpha) * (not c.alpha) shr 16); + a12m := a12 shr 1; + + a1f := merge.alpha * (not c.alpha) shr 16; + a2f := c.alpha - (c.alpha shr 15); + + merge.red := (merge.red * a1f + c.red * a2f + a12m) div a12; + merge.green := (merge.green * a1f + c.green * a2f + a12m) div a12; + merge.blue := (merge.blue * a1f + c.blue * a2f + a12m) div a12; + merge.alpha := a12 + (a12 shr 15); +end; + +procedure TIntfFreeTypeDrawer.DrawPixel(x, y: integer; const c: TFPColor); +var + merge: TFPColor; +begin + if c.alpha = 0 then exit; + if c.alpha = $ffff then + Destination.Colors[x,y] := c + else + begin + merge := Destination.Colors[x,y]; + MergeColorOver(merge,c); + Destination.Colors[x,y] := merge; + end; +end; + +procedure TIntfFreeTypeDrawer.DrawVertLine(x, y1, y2: integer; const c: TFPColor + ); +var y: integer; +begin + if (x < 0) or (x >= Destination.Width) then exit; + if (y1 > y2) then + begin + y := y1; + y1:= y2; + y2 := y; + end; + if y1 < 0 then y1 := 0; + if y2 >= Destination.Height then y2 := Destination.Height-1; + for y := y1 to y2 do + DrawPixel(x,y, c); +end; + +procedure TIntfFreeTypeDrawer.ClearTypePixel(x, y: integer; Cr, Cg, Cb: byte; Color: TFPColor); +var merge,mergeClearType: TFPColor; + acc: longword; + keep,dont_keep: word; +begin + Cr := Cr*color.alpha div 65535; + Cg := Cg*color.alpha div 65535; + Cb := Cb*color.alpha div 65535; + acc := Cr+Cg+Cb; + if acc = 0 then exit; + + merge := Destination.Colors[x,y]; + mergeClearType.red := (merge.red * (not byte(Cr)) + + color.red * Cr + 128) div 255; + mergeClearType.green := (merge.green * (not byte(Cg)) + + color.green * Cg + 128) div 255; + mergeClearType.blue := (merge.blue * (not byte(Cb)) + + color.blue * Cb + 128) div 255; + mergeClearType.alpha := merge.alpha; + + if (mergeClearType.alpha = $ffff) then + Destination.Colors[x,y]:= mergeClearType + else + begin + if Cg <> 0 then + begin + Color.alpha := Color.alpha*Cg div 255; + MergeColorOver(merge,color); + end; + dont_keep := mergeClearType.alpha shr 1; + if dont_keep > 0 then + begin + keep := 32767 - dont_keep; + merge.red := (merge.red * keep + mergeClearType.red * dont_keep) div 32767; + merge.green := (merge.green * keep + mergeClearType.green * dont_keep) div 32767; + merge.blue := (merge.blue * keep + mergeClearType.blue * dont_keep) div 32767; + merge.alpha := mergeClearType.alpha + ((not mergeClearType.alpha)*merge.alpha div 65535); + end; + Destination.Colors[x,y] := merge; + end; +end; + +procedure TIntfFreeTypeDrawer.RenderDirectly( x,y,tx: integer; + data: pointer ); +var psrc: pbyte; + c: TFPColor; +begin + if Destination <> nil then + begin + //ensure rendering in bounds + if (y < 0) or (y >= Destination.height) or (x < 0) or (x > Destination.width-tx) then exit; + + c := FColor; + psrc := pbyte(data); + while tx > 0 do + begin + c.alpha:= FColor.alpha * psrc^ div 255; + DrawPixel(x,y,c); + inc(psrc); + inc(x); + dec(tx); + end; + end; +end; + +procedure TIntfFreeTypeDrawer.RenderDirectlyClearType(x, y, tx: integer; data: pointer); +var xb: integer; + psrc: pbyte; + Cr,Cg,Cb: byte; +begin + if Destination <> nil then + begin + //ClearType position in third of pixels horizontally (multiple of 3) + x := x div 3; + tx := tx div 3; + //ensure rendering in bounds + if (y < 0) or (y >= Destination.height) or (x < 0) or (x > Destination.width-tx) then exit; + if tx=0 then exit; + + psrc := pbyte(data); + Cr := (psrc^ + psrc^ + (psrc+1)^) div 3; + Cg := (psrc^+ (psrc+1)^ + (psrc+2)^) div 3; + if tx > 1 then + Cb := ((psrc+1)^ + (psrc+2)^ + (psrc+3)^) div 3 + else + Cb := ((psrc+1)^ + (psrc+2)^ + (psrc+2)^) div 3; + ClearTypePixel(x,y,Cr,Cg,Cb, FColor); + inc(x); + inc(psrc,3); + for xb := 1 to tx-2 do + begin + Cr := ((psrc-1)^+ psrc^ + (psrc+1)^) div 3; + Cg := (psrc^+ (psrc+1)^ + (psrc+2)^) div 3; + Cb := ((psrc+1)^ + (psrc+2)^ + (psrc+3)^) div 3; + ClearTypePixel(x,y,Cr,Cg,Cb, FColor); + inc(x); + inc(psrc,3); + end; + if tx > 1 then + begin + Cr := ((psrc-1)^+ psrc^ + (psrc+1)^) div 3; + Cg := (psrc^+ (psrc+1)^ + (psrc+2)^) div 3; + Cb := ((psrc+1)^ + (psrc+2)^ + (psrc+2)^) div 3; + ClearTypePixel(x,y,Cr,Cg,Cb, FColor); + end; + end; +end; + +constructor TIntfFreeTypeDrawer.Create(ADestination: TLazIntfImage); +begin + Destination := ADestination; + ClearTypeRGBOrder:= true; +end; + +procedure TIntfFreeTypeDrawer.ClippedDrawPixel(x, y: integer; const c: TFPColor + ); +begin + if (x < 0) or (y < 0) or (x >= Destination.Width) or (y >= Destination.Height) then exit; + DrawPixel(x,y,c); +end; + +procedure TIntfFreeTypeDrawer.DrawText(AText: string; + AFont: TFreeTypeRenderableFont; x, y: single; AColor: TFPColor; AOpacity: Byte); +var col: TFPColor; +begin + col := AColor; + col.alpha := AOpacity + (AOpacity shl 8); + DrawText(AText, AFont, x,y, col); +end; + +procedure TIntfFreeTypeDrawer.DrawText(AText: string; AFont: TFreeTypeRenderableFont; x, y: single; + AColor: TFPColor); +begin + FColor := AColor; + if AFont.ClearType then + AFont.RenderText(AText, x, y, rect(0,0,Destination.Width,Destination.Height), @RenderDirectlyClearType) + else + AFont.RenderText(AText, x, y, rect(0,0,Destination.Width,Destination.Height), @RenderDirectly); +end; + +destructor TIntfFreeTypeDrawer.Destroy; +begin + inherited Destroy; +end; + +end. + + diff --git a/lcl/lclbase.lpk b/lcl/lclbase.lpk index fe23bd1c44..9a22e2ff9e 100644 --- a/lcl/lclbase.lpk +++ b/lcl/lclbase.lpk @@ -31,7 +31,7 @@ - + @@ -1189,6 +1189,10 @@ + + + + @@ -1211,5 +1215,8 @@ + + <_ExternHelp Items="Count"/> +