Blending semi-transparent bitmaps containing text with Graphics32

Viewed 772

I'm trying to implement a layered painting system inside one of our internal components and I have problems blending bitmaps containing text.

Following code fragment shows the problem:

uses
  GR32;

procedure DrawBitmaps;
var
  bmp1: TBitmap32;
  bmp2: TBitmap32;
begin
  bmp1 := TBitmap32.Create;
  bmp1.Width := 100;
  bmp1.Height := 100;
  bmp1.FillRect(0, 0, 100, 100, clWhite32);
  bmp1.FillRect(0, 0, 80, 80, clTrGreen32);

  bmp1.Font.Size := -16;
  bmp1.Font.Color := clBlack;
  bmp1.TextOut(2, 10, 'Green');

  bmp1.SaveToFile('c:\0\bmp1.bmp');

  bmp2 := TBitmap32.Create;
  bmp2.Width := 80;
  bmp2.Height := 80;
  bmp2.FillRect(0, 0, 80, 80, clTrRed32);

  bmp2.Font.Size := -16;
  bmp2.Font.Color := clBlack;
  bmp2.TextOut(2, 50, 'Red');

  bmp2.SaveToFile('c:\0\bmp2.bmp');

  bmp2.DrawMode := dmBlend;
  bmp2.DrawTo(bmp1, 20, 20);

  bmp1.SaveToFile('c:\0\bmpcombined.bmp');

  bmp1.Free;
  bmp2.Free;
end;

Resulting images:

bmp1: bmp1 bmp2: bmp2 bmpcombined: combined

As you can see, text is painted in black on bmp and bmp2, but appears white on bmpcombined.

I'm guessing the problem lies in TextOut which maps to Windows.ExtTextOut (via GR32_Backends_VCL.pas, TGDIBackend.Textout). That method doesn't handle transparency and paints text with alpha 00 (color is $000000 instead of $FF000000).

As a quick fix, setting bmp2.Font.Color to $FF000000 doesn't help.

bmp2.Font.Color := TColor(clBlack32);

I am using fresh sources from GitHub

How should I paint a non-transparent text on a semi-transparent background so that I could blend this into a larger picture?

2 Answers
Related