LazMapViewer: Rework text drawing in TRGBGraphicsDrawingEngine to avoid by-pass to LazIntfImage in favour of built-in graphics routines.
git-svn-id: https://svn.code.sf.net/p/lazarus-ccr/svn@9313 8e941d3f-bd1b-0410-a28a-d453659cc2b4
This commit is contained in:
parent
9be8f8eb5e
commit
7d571238f8
@ -17,9 +17,9 @@ unit mvDE_RGBGraphics;
|
||||
interface
|
||||
|
||||
uses
|
||||
Classes, SysUtils, Types, Graphics, IntfGraphics,
|
||||
mvDrawingEngine, mvCache,
|
||||
rgbGraphics, rgbTypes;
|
||||
Classes, SysUtils, Types, Graphics,
|
||||
mvTypes, mvDrawingEngine, mvCache,
|
||||
rgbGraphics, rgbTypes, rgbRoutines;
|
||||
|
||||
type
|
||||
|
||||
@ -51,6 +51,7 @@ type
|
||||
FPenStyle: TPenStyle;
|
||||
FPenWidth: Integer;
|
||||
protected
|
||||
procedure DrawBitmapOT(X, Y: Integer; ABitmap: TCustomBitmap; AOpaqueColor, ATransparentColor: TColor);
|
||||
function GetPenStyle: TPenStyle; override;
|
||||
function GetBrushColor: TColor; override;
|
||||
function GetBrushStyle: TBrushStyle; override;
|
||||
@ -100,35 +101,106 @@ procedure Register;
|
||||
implementation
|
||||
|
||||
uses
|
||||
GraphType, LCLType, FPImage, Math,
|
||||
mvTypes, RGBRoutines;
|
||||
GraphType, LCLType, FPImage, Math;
|
||||
|
||||
procedure Register;
|
||||
begin
|
||||
RegisterComponents(PALETTE_PAGE, [TMvRGBGraphicsDrawingEngine]);
|
||||
end;
|
||||
|
||||
{ We must duplicate some routines from rgbTypes which are not accessible. }
|
||||
|
||||
{$ifdef LCLwin32}
|
||||
{$define RGB}
|
||||
{$endif}
|
||||
{$ifdef LCLqt}
|
||||
{$define RGB}
|
||||
{$endif}
|
||||
{$ifdef LCLqt5}
|
||||
{$define RGB}
|
||||
{$endif}
|
||||
{$ifdef LCLqt6}
|
||||
{$define RGB}
|
||||
{$endif}
|
||||
|
||||
function GetRedInline(P: TRGB32Pixel): Byte; inline;
|
||||
begin
|
||||
{$IFDEF RGB}
|
||||
Result := (P and $FF0000) shr 16;
|
||||
{$ELSE}
|
||||
Result := P and $FF;
|
||||
{$ENDIF}
|
||||
end;
|
||||
|
||||
function GetGreenInline(P: TRGB32Pixel): Byte; inline;
|
||||
begin
|
||||
{$IFDEF RGB}
|
||||
Result := (P and $FF00) shr 8;
|
||||
{$ELSE}
|
||||
Result := (P and $FF00) shr 8;
|
||||
{$ENDIF}
|
||||
end;
|
||||
|
||||
function GetBlueInline(P: TRGB32Pixel): Byte; inline;
|
||||
begin
|
||||
{$IFDEF RGB}
|
||||
Result := P and $FF;
|
||||
{$ELSE}
|
||||
Result := (P and $FF0000) shr 16;
|
||||
{$ENDIF}
|
||||
end;
|
||||
|
||||
function RGBToRGB32PixelInline(R, G, B: Byte): TRGB32Pixel; inline;
|
||||
begin
|
||||
{$IFDEF RGB}
|
||||
Result := B or (G shl 8) or (R shl 16);
|
||||
{$ELSE}
|
||||
Result := R or (G shl 8) or (B shl 16);
|
||||
{$ENDIF}
|
||||
end;
|
||||
|
||||
function ColorToRGB32PixelInline(C: TColor): TRGB32Pixel; inline;
|
||||
begin
|
||||
{$IFDEF RGB}
|
||||
Result := ((C and $FF0000) shr 16) or (C and $FF00) or ((C and $FF) shl 16);
|
||||
{$ELSE}
|
||||
Result := C and $FFFFFF;
|
||||
{$ENDIF}
|
||||
end;
|
||||
|
||||
function CalculateGray(P: TRGB32Pixel): Byte; inline;
|
||||
var
|
||||
r, g, b: Byte;
|
||||
begin
|
||||
r := GetRedInline(P);
|
||||
g := GetGreenInline(P);
|
||||
b := GetBlueInline(P);
|
||||
Result := round(0.299 * r + 0.587 * g + 0.114 * b);
|
||||
end;
|
||||
|
||||
// P1 points to background pixel, P2 to overlay image pixel
|
||||
procedure AlphaBlendRGB32Pixel(Alpha: Byte; P1, P2, AResult: PRGB32Pixel); inline;
|
||||
var
|
||||
r1, g1, b1: Byte;
|
||||
r2, g2, b2: Byte;
|
||||
begin
|
||||
r1 := P1^;
|
||||
g1 := P1^ shr 8;
|
||||
b1 := P1^ shr 16;
|
||||
r1 := GetRedInline(P1^);
|
||||
g1 := GetGreenInline(P1^);
|
||||
b1 := GetBlueInline(P1^);
|
||||
|
||||
r2 := P2^;
|
||||
g2 := P2^ shr 8;
|
||||
b2 := P2^ shr 16;
|
||||
r2 := GetRedInline(P2^);
|
||||
g2 := GetGreenInline(P2^);
|
||||
b2 := GetBlueInline(P2^);
|
||||
|
||||
r1 := (word((255 - Alpha) * r1) + word(Alpha) * r2) shr 8;
|
||||
g1 := (word((255 - Alpha) * g1) + word(Alpha) * g2) shr 8;
|
||||
b1 := (word((255 - Alpha) * b1) + word(Alpha) * b2) shr 8;
|
||||
|
||||
AResult^ := r1 + g1 shl 8 + b1 shl 16;
|
||||
AResult^ := RGBToRGB32PixelInline(r1, g1, b1);
|
||||
end;
|
||||
|
||||
procedure AlphaBlendImages(ABackground, ABitmap: TRGB32Bitmap; X, Y: Integer; AAlpha: Byte);
|
||||
procedure AlphaBlendImages(ABackground, ABitmap: TRGB32Bitmap; X, Y: Integer;
|
||||
AAlpha: Byte = -1);
|
||||
var
|
||||
BkgX, BkgY, XMax, YMax, I, J, ImgX, ImgY: Integer;
|
||||
P1, P2: PRGB32Pixel;
|
||||
@ -145,7 +217,7 @@ begin
|
||||
begin
|
||||
P1 := ABackground.Get32PixelPtr(BkgX, BkgY + J);
|
||||
P2 := ABitmap.Get32PixelPtr(ImgX, ImgY + J);
|
||||
if AAlpha > 0 then
|
||||
if AAlpha >= 0 then
|
||||
for I := 0 to XMax do
|
||||
begin
|
||||
AlphaBlendRGB32Pixel(AAlpha, P1, P2, P1);
|
||||
@ -166,6 +238,7 @@ begin
|
||||
end;
|
||||
end;
|
||||
|
||||
|
||||
{ TRGB32BitmapCacheItem }
|
||||
|
||||
function TRGB32BitmapCacheItem.GetImage: TRGB32Bitmap;
|
||||
@ -215,33 +288,74 @@ begin
|
||||
FBuffer := TRGB32Bitmap.Create(AWidth, AHeight);
|
||||
end;
|
||||
|
||||
procedure TMvRGBGraphicsDrawingEngine.DrawBitmap(X,Y: Integer;
|
||||
procedure TMvRGBGraphicsDrawingEngine.DrawBitmap(X, Y: Integer;
|
||||
ABitmap: TCustomBitmap; UseAlphaChannel: Boolean);
|
||||
var
|
||||
intfImg: TLazIntfImage;
|
||||
i, j: Integer;
|
||||
cimg, cbuf: TFPColor;
|
||||
alpha: Double;
|
||||
bmp32: TRGB32Bitmap;
|
||||
begin
|
||||
intfImg := ABitmap.CreateIntfImage;
|
||||
bmp32 := TRGB32Bitmap.CreateFromBitmap(ABitmap);
|
||||
try
|
||||
if UseAlphaChannel then begin
|
||||
for j := 0 to intfImg.Height - 1 do
|
||||
for i := 0 to intfImg.Width - 1 do begin
|
||||
cimg := intfImg.Colors[i, j];
|
||||
alpha := cimg.Alpha / word($FFFF);
|
||||
cbuf := TColorToFPColor(FBuffer.Canvas.GetColor(i + X, j + Y));
|
||||
cbuf.Red := Round(alpha * cimg.Red + (1 - alpha) * cbuf.Red);
|
||||
cbuf.Green := Round(alpha * cimg.Green + (1 - alpha) * cbuf.Green);
|
||||
cbuf.Blue := Round(alpha * cimg.Blue + (1 - alpha) * cbuf.Blue);
|
||||
FBuffer.Canvas.SetColor(i + X, j + Y, FPColorToTColor(cbuf));
|
||||
end;
|
||||
end else
|
||||
for j := 0 to intfImg.Height - 1 do
|
||||
for i := 0 to intfImg.Width - 1 do
|
||||
FBuffer.Canvas.SetColor(i + X, j + Y, FPColorToTColor(intfImg.Colors[i, j]));
|
||||
if UseAlphaChannel then
|
||||
AlphaBlendImages(FBuffer, bmp32, X, Y)
|
||||
else
|
||||
FBuffer.Draw(X, Y, bmp32);
|
||||
finally
|
||||
intfimg.Free;
|
||||
bmp32.Free;
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure TMvRGBGraphicsDrawingEngine.DrawBitmapOT(X, Y: Integer;
|
||||
ABitmap: TCustomBitmap; AOpaqueColor, ATransparentColor: TColor);
|
||||
var
|
||||
bmp32: TRGB32Bitmap;
|
||||
BkgX, BkgY, XMax, YMax, I, J, ImgX, ImgY: Integer;
|
||||
P1, P2: PRGB32Pixel;
|
||||
alpha: PRGB8Pixel;
|
||||
transpPixel, opaquePixel, workPixel: TRGB32Pixel;
|
||||
gray, bkGray: Word;
|
||||
begin
|
||||
BkgX := Max(0, X);
|
||||
BkgY := Max(0, Y);
|
||||
ImgX := Max(0, -X);
|
||||
ImgY := Max(0, -Y);
|
||||
XMax := Min(ABitmap.Width - ImgX, FBuffer.Width - BkgX) - 1;
|
||||
YMax := Min(ABitmap.Height - ImgY, FBuffer.Height - BkgY) - 1;
|
||||
opaquePixel := ColorToRGB32PixelInline(AOpaqueColor);
|
||||
transpPixel := ColorToRGB32PixelInline(ATransparentColor);
|
||||
bkGray := CalculateGray(transpPixel);
|
||||
|
||||
bmp32 := TRGB32Bitmap.CreateFromBitmap(ABitmap);
|
||||
try
|
||||
for J := YMax downto 0 do
|
||||
begin
|
||||
P1 := FBuffer.Get32PixelPtr(BkgX, BkgY + J);
|
||||
P2 := bmp32.Get32PixelPtr(ImgX, ImgY + J);
|
||||
alpha := bmp32.Mask.Get8PixelPtr(ImgX, ImgY + J);
|
||||
for I := 0 to XMax do
|
||||
begin
|
||||
workPixel := P2^ and $00FFFFFF;
|
||||
if workPixel = transpPixel then
|
||||
alpha^ := 0
|
||||
else
|
||||
if workPixel = opaquePixel then
|
||||
alpha^ := 255
|
||||
else
|
||||
begin
|
||||
gray := CalculateGray(P2^);
|
||||
workPixel := opaquePixel;
|
||||
if gray > bkGray then
|
||||
alpha^ := gray - bkGray
|
||||
else
|
||||
alpha^ := bkGray - gray;
|
||||
end;
|
||||
AlphaBlendRGB32Pixel(alpha^, P1, @workPixel, P1);
|
||||
inc(P1);
|
||||
inc(P2);
|
||||
inc(alpha);
|
||||
end;
|
||||
end;
|
||||
finally
|
||||
bmp32.Free;
|
||||
end;
|
||||
end;
|
||||
|
||||
@ -527,60 +641,6 @@ begin
|
||||
end;
|
||||
end;
|
||||
|
||||
(*
|
||||
procedure TMvRGBGraphicsDrawingEngine.TextOut(X, Y: Integer; const AText: String);
|
||||
var
|
||||
bmp: TBitmap;
|
||||
ex: TSize;
|
||||
img: TLazIntfImage;
|
||||
brClr: TFPColor;
|
||||
imgClr: TFPColor;
|
||||
i, j: Integer;
|
||||
begin
|
||||
if (AText = '') then
|
||||
exit;
|
||||
|
||||
bmp := TBitmap.Create;
|
||||
try
|
||||
bmp.PixelFormat := pf32Bit;
|
||||
bmp.SetSize(1, 1);
|
||||
bmp.Canvas.Font.Name := FFontName;
|
||||
bmp.Canvas.Font.Size := FFontSize;
|
||||
bmp.Canvas.Font.Style := FFontStyle;
|
||||
bmp.Canvas.Font.Color := FFontColor;
|
||||
ex := bmp.Canvas.TextExtent(AText);
|
||||
bmp.SetSize(ex.CX, ex.CY);
|
||||
bmp.Canvas.Brush.Color := GetBrushColor;
|
||||
if GetBrushStyle = bsClear then
|
||||
bmp.Canvas.Brush.Style := bsSolid
|
||||
else
|
||||
bmp.Canvas.Brush.Style := GetBrushStyle;
|
||||
bmp.Canvas.FillRect(0, 0, bmp.Width, bmp.Height);
|
||||
bmp.Canvas.TextOut(0, 0, AText);
|
||||
img := bmp.CreateIntfImage;
|
||||
try
|
||||
if GetBrushStyle = bsClear then begin
|
||||
brClr := TColorToFPColor(GetBrushColor);
|
||||
for j := 0 to img.Height - 1 do
|
||||
for i := 0 to img.Width - 1 do begin
|
||||
imgClr := img.Colors[i, j];
|
||||
if (imgClr.Red = brClr.Red) and (imgClr.Green = brClr.Green) and (imgClr.Blue = brClr.Blue) then
|
||||
Continue;
|
||||
FBuffer.Canvas.SetColor(X + i, Y + j, FPColorToTColor(imgClr));
|
||||
end;
|
||||
end else
|
||||
for j := 0 to img.Height - 1 do
|
||||
for i := 0 to img.Width - 1 do
|
||||
FBuffer.Canvas.SetColor(X + i, Y + j, FPColorToTColor(img.Colors[i, j]));
|
||||
finally
|
||||
img.Free;
|
||||
end;
|
||||
finally
|
||||
bmp.Free;
|
||||
end;
|
||||
end;
|
||||
*)
|
||||
|
||||
procedure TMvRGBGraphicsDrawingEngine.TextOut(X, Y: Integer; const AText: String);
|
||||
var
|
||||
bmp: TBitmap;
|
||||
@ -590,8 +650,7 @@ begin
|
||||
exit;
|
||||
bmp := TBitmap.Create;
|
||||
try
|
||||
bmp.PixelFormat := pf32Bit;
|
||||
bmp.SetSize(1, 1);
|
||||
bmp.PixelFormat := pf24Bit; // Does not work with 32 bpp...
|
||||
bmp.Canvas.Font.Name := FFontName;
|
||||
bmp.Canvas.Font.Size := FFontSize;
|
||||
bmp.Canvas.Font.Style := FFontStyle;
|
||||
|
@ -53,7 +53,6 @@ type
|
||||
procedure CreateBuffer(AWidth, AHeight: Integer); virtual; abstract;
|
||||
procedure DrawBitmap(X, Y: Integer; ABitmap: TCustomBitmap;
|
||||
UseAlphaChannel: Boolean); virtual; abstract;
|
||||
// Drawing bitmap with a given opaque and transparent colors
|
||||
procedure DrawCacheItem(X, Y: Integer; AImg: TPictureCacheItem;
|
||||
ADrawMode: TItemDrawMode = idmDraw; AOpacity: Single = 1.0); virtual; abstract;
|
||||
procedure DrawScaledCacheItem(DestRect, SrcRect: TRect; AImg: TPictureCacheItem); virtual; abstract;
|
||||
|
Loading…
Reference in New Issue
Block a user