Sign in Join

Live chat for Free Pascal, Lazarus, Delphi and every Pascal programmer.

Mailing lists / lazarus / 2011-07

Transparent (key color based) drawing questions

4 messages · 3 people · –

Reply by email Subscribe to this list Your subscription

Read-only archive. Use j and k to move between messages.

Max Vlasov

Hi,
I used the technique described here
http://wiki.lazarus.freepascal.org/Developing_with_Graphics#Drawing_color_transparent_bitmaps for transparent drawing on windows. So when porting to cross-platform used this example.

Two observations:

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;

because probably in the first case the color assignment invalidates Masked (= Transparent). Seems like every next call is ok because the mask is already created. If my case when the program started, the result was non-transparent, and the problem is fixed only when I mimimize and restore the window

Either it would be great to fix this in the example (mentioning this side effect in the comment) or change the code to be more universal.

2. Another moment is that as I see Canvas.CopyRect is not compatible with this transparent drawing. At least I see no visual results and no masked procedures are called. Probably this is by design, but this means that it's not possible to draw different parts of transparent bitmaps. Currently I copied and adapted the lines from TRasterImage.Draw, but the suggestion is to create public, method (non-existed before) for advanced drawing and TRasterImage.Draw just will use it with some default parameters. Actually this method won't be a threat for the binary size increase because TRasterImage.Draw is already ready for this, just uses four hard-coded zeros in the StretchMaskBlt call

Also maybe CopyRect incompatibility is also worth mentioning in the example

Thank you,

Max

Reply by email

Felipe Monteiro de Carvalho
to Max Vlasov
Max Vlasov wrote 9 lines
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;

If your version works in windows too, then you can simply fix the wiki.

Felipe Monteiro de Carvalho

Reply by email

Flávio Etrusco
to Max Vlasov: I used the technique described here http://wiki.lazarus.freepascal.org/Developing_with_Gra…
Max Vlasov wrote 27 lines
Hi, I used the technique described here ?http://wiki.lazarus.freepascal.org/Developing_with_Graphics#Drawing_color_transparent_bitmaps for transparent drawing on windows. So when porting to cross-platform used this example. Two observations: 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; because probably in the first case the color assignment invalidates Masked (= Transparent). Seems like every next call is ok because the mask is already created. If my case when the program started, the result was non-transparent, and the problem is fixed only when I mimimize and restore the window Either it would be great to fix this in the example (mentioning this side effect in the comment) or change the code to be more universal.

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.

Best regards,
Fl?vio

Reply by email

Max Vlasov
to Flávio Etrusco

2011/7/14 Fl?vio Etrusco :

Show quoted text 21 lines
On Thu, Jul 14, 2011 at 7:37 AM, Max Vlasov 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

Reply by email