[Lazarus] Transparent (key color based) drawing questions
Max Vlasov
max.vlasov at gmail.com
Fri Jul 15 09:54:53 CEST 2011
2011/7/14 Flávio Etrusco <flavio.etrusco at gmail.com>:
> On Thu, Jul 14, 2011 at 7:37 AM, Max Vlasov <max.vlasov at gmail.com> wrote:
>> 1. At least on linux gtk the order of assignments should be reverse
>>
>> On the site
>> bmp.Transparent := True;
>> bmp.TransparentColor := clFuchsia;
>>
>> But the correct order is
>> bmp.TransparentColor := clFuchsia;
>> bmp.Transparent := True;
>>
>
> What's the exact code? Can you debug and check TGraphic.Changed is
> being called after TransparentColor is invoked in the first example?
> Looking at the TRasterImage code, SetTransparent always invoke
> Changed, but SetTransparentColor has a more complex handling.
> Anyway I agree it's worth changing the wiki; the mask generation is
> delayed until it's needed, so the order won't make a difference in the
> example, but depending on what's done in OnChange it can easily
> trigger the mask generation twice.
>
I tried to look deeper,
for general usage the order is really doesn't matter
So
procedure TForm1.PaintBox1Paint(Sender: TObject);
begin
fBmp.Transparent:=true;
fBmp.TransparentColor:=clBlack;
PaintBox1.Canvas.Draw(0, 0, fBmp);
end;
works.
But in my case during the internal actions the handle of the bitmap
was required before the first drawing, so changing the sequence to
...
fBmp.Handle;
fBmp.Transparent:=true;
fBmp.TransparentColor:=clBlack;
PaintBox1.Canvas.Draw(0, 0, fBmp);
...
triggers the problem. The next calls work because Transparent:=
returns the mask and TransparentColor:= does nothing since the color
is the same.
I looked and walked at the sources, the fragment from
TRasterImage.SetTransparentColor is
if MaskHandleAllocated
then MaskHandle := 0
else Changed(Self);
then part is called (because the mask was allocated before as the
result of handle requesting) and because of this 'then' part
MaskHandle:= 0 changes fMasked property to false. So the drawing is
now non-transparent. The quick patch is to change it to
if MaskHandleAllocated then
begin
svMasked:=Masked;
MaskHandle := 0;
Masked:=svMasked;
end
else Changed(Self);
But the property itself (Masked) currently is already hard to track
since it's depends on several states:
- can be changed directly with Transparent:=
- indirectly changed by MaskHandle:=
So I don't know whether it's better to do such quick hack or maybe
rethink the internal logic a littel.
Max
More information about the Lazarus
mailing list